@@ -27,7 +27,6 @@ use rustc_infer::infer::TypeTrace;
2727use rustc_infer:: traits:: PredicateObligation ;
2828use rustc_middle:: ty:: adjustment:: AllowTwoPhase ;
2929use rustc_middle:: ty:: visit:: TypeVisitable ;
30- use rustc_middle:: ty:: walk:: TypeWalker ;
3130use rustc_middle:: ty:: { self , DefIdTree , IsSuggestable , Ty , TypeSuperVisitable , TypeVisitor } ;
3231use rustc_session:: Session ;
3332use rustc_span:: symbol:: { kw, Ident } ;
@@ -525,7 +524,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
525524 // Sometimes macros mess up the spans, so do not normalize the
526525 // arg span to equal the error span, because that's less useful
527526 // than pointing out the arg expr in the wrong context.
528- if normalized_span. source_equal ( error_span) { span } else { normalized_span }
527+ if normalized_span. source_equal ( error_span) {
528+ span
529+ } else {
530+ normalized_span
531+ }
529532 } ;
530533
531534 // Precompute the provided types and spans, since that's all we typically need for below
@@ -778,9 +781,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
778781 // can be collated pretty easily if needed.
779782
780783 // Next special case: if there is only one "Incompatible" error, just emit that
781- if let [
782- Error :: Invalid ( provided_idx, expected_idx, Compatibility :: Incompatible ( Some ( err) ) ) ,
783- ] = & errors[ ..]
784+ if let [ Error :: Invalid ( provided_idx, expected_idx, Compatibility :: Incompatible ( Some ( err) ) ) ] =
785+ & errors[ ..]
784786 {
785787 let ( formal_ty, expected_ty) = formal_and_expected_inputs[ * expected_idx] ;
786788 let ( provided_ty, provided_arg_span) = provided_arg_tys[ * provided_idx] ;
@@ -1522,25 +1524,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15221524 // Our block must be a `assign desugar local; assignment`
15231525 if let Some ( hir:: Node :: Block ( hir:: Block {
15241526 stmts :
1525- [
1526- hir:: Stmt {
1527- kind :
1528- hir:: StmtKind :: Local ( hir:: Local {
1529- source :
1530- hir:: LocalSource :: AssignDesugar ( _) ,
1531- ..
1532- } ) ,
1533- ..
1534- } ,
1535- hir:: Stmt {
1536- kind :
1537- hir:: StmtKind :: Expr ( hir:: Expr {
1538- kind : hir:: ExprKind :: Assign ( ..) ,
1539- ..
1540- } ) ,
1541- ..
1542- } ,
1543- ] ,
1527+ [ hir:: Stmt {
1528+ kind :
1529+ hir:: StmtKind :: Local ( hir:: Local {
1530+ source : hir:: LocalSource :: AssignDesugar ( _) ,
1531+ ..
1532+ } ) ,
1533+ ..
1534+ } , hir:: Stmt {
1535+ kind :
1536+ hir:: StmtKind :: Expr ( hir:: Expr {
1537+ kind : hir:: ExprKind :: Assign ( ..) ,
1538+ ..
1539+ } ) ,
1540+ ..
1541+ } ] ,
15441542 ..
15451543 } ) ) = self . tcx . hir ( ) . find ( blk. hir_id )
15461544 {
@@ -1942,7 +1940,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19421940 . inputs ( )
19431941 . iter ( )
19441942 . enumerate ( )
1945- . filter ( |( _, ty) | find_param_in_ty ( * * ty, param_to_point_at) )
1943+ . filter ( |( _, ty) | find_param_in_ty ( ( * * ty) . into ( ) , param_to_point_at) )
19461944 . collect ( ) ;
19471945 // If there's one field that references the given generic, great!
19481946 if let [ ( idx, _) ] = args_referencing_param. as_slice ( )
@@ -2081,7 +2079,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20812079 ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( broken_trait) ) => relevant_impl_generics
20822080 . filter ( |& generic| {
20832081 // Only retain generics that are mentioned in the (Self type) of this predicate:
2084- find_param_def_in_ty_walker ( broken_trait. trait_ref . self_ty ( ) . walk ( ) , generic)
2082+ find_param_in_ty (
2083+ broken_trait. trait_ref . self_ty ( ) . into ( ) ,
2084+ self . tcx . mk_param_from_def ( generic) ,
2085+ )
20852086 } )
20862087 . collect ( ) ,
20872088 _ => {
@@ -2099,14 +2100,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20992100 // since we cannot refine such a span any more anyway.
21002101 // Right now, only ADTs (struct/enum (variant) constructors) and tuples are supported by this refinement.
21012102 let ( impl_self_ty, impl_self_ty_args) = match impl_self_ty. kind ( ) {
2102- ty:: Adt ( impl_self_ty_path, impl_self_ty_args) => (
2103- PointableType :: Adt ( * impl_self_ty_path) ,
2104- impl_self_ty_args. iter ( ) . collect :: < Vec < _ > > ( ) ,
2105- ) ,
2106- ty:: Tuple ( impl_self_ty_args) => (
2107- PointableType :: Tuple ,
2108- impl_self_ty_args. iter ( ) . map ( |t| ty:: GenericArg :: from ( t) ) . collect :: < Vec < _ > > ( ) ,
2109- ) ,
2103+ ty:: Adt ( impl_self_ty_path, impl_self_ty_args) => {
2104+ ( PointableType :: Adt ( * impl_self_ty_path) , * impl_self_ty_args)
2105+ }
2106+ ty:: Tuple ( impl_self_ty_args) => ( PointableType :: Tuple , impl_self_ty_args. as_substs ( ) ) ,
21102107 _ => {
21112108 return Err ( expr) ;
21122109 }
@@ -2122,7 +2119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21222119 . filter ( |( _index, ty_arg) | {
21232120 relevant_impl_generics
21242121 . iter ( )
2125- . any ( |param| find_param_def_in_ty_walker ( ty_arg. walk ( ) , param) )
2122+ . any ( |param| find_param_in_ty ( * ty_arg, self . tcx . mk_param_from_def ( param) ) )
21262123 } )
21272124 . map ( |( index, _ty_arg) | index)
21282125 . collect ( ) ;
@@ -2211,9 +2208,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22112208 let field_type: Ty < ' tcx > = self . tcx . type_of ( field_def. did ) ;
22122209
22132210 // Only retain fields which mention the blameable generics.
2214- struct_def_generics
2215- . iter ( )
2216- . any ( |param| find_param_def_in_ty_walker ( field_type . walk ( ) , param ) )
2211+ struct_def_generics. iter ( ) . any ( |param| {
2212+ find_param_in_ty ( field_type . into ( ) , self . tcx . mk_param_from_def ( param ) )
2213+ } )
22172214 } )
22182215 . collect ( ) ;
22192216
@@ -2224,7 +2221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22242221
22252222 let blameable_field_def: & ty:: FieldDef = blameable_field_defs[ 0 ] ;
22262223
2227- for field in struct_fields. iter ( ) {
2224+ for field in struct_fields {
22282225 if field. ident . as_str ( ) == blameable_field_def. ident ( self . tcx ) . as_str ( ) {
22292226 // Blame this field!
22302227 return Ok ( field. expr ) ;
@@ -2277,7 +2274,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22772274 . variants ( )
22782275 . iter ( )
22792276 . find ( |variant : & & ty:: VariantDef | -> bool {
2280- variant. ctor . map ( |ctor| ctor. 1 == * ctor_def_id) . unwrap_or ( false )
2277+ variant. ctor . map_or ( false , |ctor| ctor. 1 == * ctor_def_id)
22812278 } ) ;
22822279
22832280 let Some ( struct_variant_def) = struct_variant_def else {
@@ -2295,17 +2292,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22952292 . collect ( ) ;
22962293
22972294 // The struct being constructed is the same as the struct in the impl.
2295+ // Because it's a tuple-struct-like expression, we only care about the index
2296+ // (the fields don't have real names).
22982297
2299- let blameable_field_defs: Vec < & ty:: FieldDef > = struct_variant_def
2298+ let blameable_field_defs: Vec < ( usize , & ty:: FieldDef ) > = struct_variant_def
23002299 . fields
23012300 . iter ( )
2302- . filter ( |field_def| {
2301+ . enumerate ( )
2302+ . filter ( |( _index, field_def) | {
23032303 let field_type: Ty < ' tcx > = self . tcx . type_of ( field_def. did ) ;
23042304
23052305 // Only retain fields which mention the blameable generics.
2306- struct_def_generics
2307- . iter ( )
2308- . any ( |param| find_param_def_in_ty_walker ( field_type. walk ( ) , param) )
2306+ struct_def_generics. iter ( ) . any ( |param| {
2307+ find_param_in_ty (
2308+ field_type. into ( ) ,
2309+ self . tcx . mk_param_from_def ( param) ,
2310+ )
2311+ } )
23092312 } )
23102313 . collect ( ) ;
23112314
@@ -2314,12 +2317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23142317 return Err ( expr) ;
23152318 }
23162319
2317- let blameable_field_def: & ty:: FieldDef = blameable_field_defs[ 0 ] ;
2318- let blameable_field_index = struct_variant_def
2319- . fields
2320- . iter ( )
2321- . position ( |field_def| field_def == blameable_field_def)
2322- . expect ( "exists in list" ) ;
2320+ let ( blameable_field_index, _) = blameable_field_defs[ 0 ] ;
23232321
23242322 if blameable_field_index < call_ctor_args. len ( ) {
23252323 return Ok ( & call_ctor_args[ blameable_field_index] ) ;
@@ -2394,7 +2392,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23942392 . iter ( )
23952393 . filter ( |field| {
23962394 let field_ty = field. ty ( self . tcx , identity_substs) ;
2397- find_param_in_ty ( field_ty, param_to_point_at)
2395+ find_param_in_ty ( field_ty. into ( ) , param_to_point_at)
23982396 } )
23992397 . collect ( ) ;
24002398
@@ -2636,7 +2634,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26362634 }
26372635}
26382636
2639- fn find_param_in_ty < ' tcx > ( ty : Ty < ' tcx > , param_to_point_at : ty:: GenericArg < ' tcx > ) -> bool {
2637+ /// Traverses the given ty (either a `ty::Ty` or a `ty::GenericArg`) and searches for references
2638+ /// to the given `param_to_point_at`. Returns `true` if it finds any use of the param.
2639+ fn find_param_in_ty < ' tcx > (
2640+ ty : ty:: GenericArg < ' tcx > ,
2641+ param_to_point_at : ty:: GenericArg < ' tcx > ,
2642+ ) -> bool {
26402643 let mut walk = ty. walk ( ) ;
26412644 while let Some ( arg) = walk. next ( ) {
26422645 if arg == param_to_point_at {
@@ -2655,24 +2658,3 @@ fn find_param_in_ty<'tcx>(ty: Ty<'tcx>, param_to_point_at: ty::GenericArg<'tcx>)
26552658 }
26562659 false
26572660}
2658-
2659- fn find_param_def_in_ty_walker < ' tcx > (
2660- mut walk : TypeWalker < ' tcx > ,
2661- param_to_point_at : & ' tcx ty:: GenericParamDef ,
2662- ) -> bool {
2663- let param_to_point_at_param_ty = ty:: ParamTy :: for_def ( param_to_point_at) ;
2664- while let Some ( arg) = walk. next ( ) {
2665- match arg. unpack ( ) {
2666- ty:: GenericArgKind :: Type ( arg_ty) => match arg_ty. kind ( ) {
2667- ty:: Param ( arg_param_ty) => {
2668- if arg_param_ty == & param_to_point_at_param_ty {
2669- return true ;
2670- }
2671- }
2672- _ => { }
2673- } ,
2674- _ => { }
2675- }
2676- }
2677- false
2678- }
0 commit comments