@@ -1865,6 +1865,17 @@ pub enum LvaluePreference {
18651865 NoPreference
18661866}
18671867
1868+ /// Whether `autoderef` requires types to resolve.
1869+ #[ derive( Copy , Show , PartialEq , Eq ) ]
1870+ pub enum UnresolvedTypeAction {
1871+ /// Produce an error and return `ty_err` whenever a type cannot
1872+ /// be resolved (i.e. it is `ty_infer`).
1873+ Error ,
1874+ /// Go on without emitting any errors, and return the unresolved
1875+ /// type. Useful for probing, e.g. in coercions.
1876+ Ignore
1877+ }
1878+
18681879/// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
18691880/// whether to terminate the loop. Returns the final type and number of derefs that it performed.
18701881///
@@ -1874,6 +1885,7 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
18741885 sp : Span ,
18751886 base_ty : Ty < ' tcx > ,
18761887 opt_expr : Option < & ast:: Expr > ,
1888+ unresolved_type_action : UnresolvedTypeAction ,
18771889 mut lvalue_pref : LvaluePreference ,
18781890 mut should_stop : F )
18791891 -> ( Ty < ' tcx > , uint , Option < T > )
@@ -1886,11 +1898,22 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
18861898
18871899 let mut t = base_ty;
18881900 for autoderefs in 0 ..fcx. tcx ( ) . sess . recursion_limit . get ( ) {
1889- let resolved_t = structurally_resolved_type ( fcx, sp, t) ;
1890-
1891- if ty:: type_is_error ( resolved_t) {
1892- return ( resolved_t, autoderefs, None ) ;
1893- }
1901+ let resolved_t = match unresolved_type_action {
1902+ UnresolvedTypeAction :: Error => {
1903+ let resolved_t = structurally_resolved_type ( fcx, sp, t) ;
1904+ if ty:: type_is_error ( resolved_t) {
1905+ return ( resolved_t, autoderefs, None ) ;
1906+ }
1907+ resolved_t
1908+ }
1909+ UnresolvedTypeAction :: Ignore => {
1910+ // We can continue even when the type cannot be resolved
1911+ // (i.e. it is an inference variable) because `ty::deref`
1912+ // and `try_overloaded_deref` both simply return `None`
1913+ // in such a case without producing spurious errors.
1914+ fcx. resolve_type_vars_if_possible ( t)
1915+ }
1916+ } ;
18941917
18951918 match should_stop ( resolved_t, autoderefs) {
18961919 Some ( x) => return ( resolved_t, autoderefs, Some ( x) ) ,
@@ -2011,8 +2034,13 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
20112034 // autoderef that normal method probing does. They could likely be
20122035 // consolidated.
20132036
2014- let ( ty, autoderefs, final_mt) =
2015- autoderef ( fcx, base_expr. span , base_ty, Some ( base_expr) , lvalue_pref, |adj_ty, idx| {
2037+ let ( ty, autoderefs, final_mt) = autoderef ( fcx,
2038+ base_expr. span ,
2039+ base_ty,
2040+ Some ( base_expr) ,
2041+ UnresolvedTypeAction :: Error ,
2042+ lvalue_pref,
2043+ |adj_ty, idx| {
20162044 let autoderefref = ty:: AutoDerefRef { autoderefs : idx, autoref : None } ;
20172045 step ( adj_ty, autoderefref)
20182046 } ) ;
@@ -3053,8 +3081,13 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
30533081 let expr_t = structurally_resolved_type ( fcx, expr. span ,
30543082 fcx. expr_ty ( base) ) ;
30553083 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3056- let ( _, autoderefs, field_ty) =
3057- autoderef ( fcx, expr. span , expr_t, Some ( base) , lvalue_pref, |base_t, _| {
3084+ let ( _, autoderefs, field_ty) = autoderef ( fcx,
3085+ expr. span ,
3086+ expr_t,
3087+ Some ( base) ,
3088+ UnresolvedTypeAction :: Error ,
3089+ lvalue_pref,
3090+ |base_t, _| {
30583091 match base_t. sty {
30593092 ty:: ty_struct( base_id, substs) => {
30603093 debug ! ( "struct named {}" , ppaux:: ty_to_string( tcx, base_t) ) ;
@@ -3146,8 +3179,13 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
31463179 fcx. expr_ty ( base) ) ;
31473180 let mut tuple_like = false ;
31483181 // FIXME(eddyb) #12808 Integrate privacy into this auto-deref loop.
3149- let ( _, autoderefs, field_ty) =
3150- autoderef ( fcx, expr. span , expr_t, Some ( base) , lvalue_pref, |base_t, _| {
3182+ let ( _, autoderefs, field_ty) = autoderef ( fcx,
3183+ expr. span ,
3184+ expr_t,
3185+ Some ( base) ,
3186+ UnresolvedTypeAction :: Error ,
3187+ lvalue_pref,
3188+ |base_t, _| {
31513189 match base_t. sty {
31523190 ty:: ty_struct( base_id, substs) => {
31533191 tuple_like = ty:: is_tuple_struct ( tcx, base_id) ;
0 commit comments