@@ -27,7 +27,6 @@ use rustc_infer::infer::TypeTrace;
27
27
use rustc_infer:: traits:: PredicateObligation ;
28
28
use rustc_middle:: ty:: adjustment:: AllowTwoPhase ;
29
29
use rustc_middle:: ty:: visit:: TypeVisitable ;
30
- use rustc_middle:: ty:: walk:: TypeWalker ;
31
30
use rustc_middle:: ty:: { self , DefIdTree , IsSuggestable , Ty , TypeSuperVisitable , TypeVisitor } ;
32
31
use rustc_session:: Session ;
33
32
use rustc_span:: symbol:: { kw, Ident } ;
@@ -525,7 +524,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
525
524
// Sometimes macros mess up the spans, so do not normalize the
526
525
// arg span to equal the error span, because that's less useful
527
526
// 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
+ }
529
532
} ;
530
533
531
534
// 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> {
778
781
// can be collated pretty easily if needed.
779
782
780
783
// 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[ ..]
784
786
{
785
787
let ( formal_ty, expected_ty) = formal_and_expected_inputs[ * expected_idx] ;
786
788
let ( provided_ty, provided_arg_span) = provided_arg_tys[ * provided_idx] ;
@@ -1522,25 +1524,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1522
1524
// Our block must be a `assign desugar local; assignment`
1523
1525
if let Some ( hir:: Node :: Block ( hir:: Block {
1524
1526
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
+ } ] ,
1544
1542
..
1545
1543
} ) ) = self . tcx . hir ( ) . find ( blk. hir_id )
1546
1544
{
@@ -1942,7 +1940,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1942
1940
. inputs ( )
1943
1941
. iter ( )
1944
1942
. 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) )
1946
1944
. collect ( ) ;
1947
1945
// If there's one field that references the given generic, great!
1948
1946
if let [ ( idx, _) ] = args_referencing_param. as_slice ( )
@@ -2081,7 +2079,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2081
2079
ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( broken_trait) ) => relevant_impl_generics
2082
2080
. filter ( |& generic| {
2083
2081
// 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
+ )
2085
2086
} )
2086
2087
. collect ( ) ,
2087
2088
_ => {
@@ -2099,14 +2100,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2099
2100
// since we cannot refine such a span any more anyway.
2100
2101
// Right now, only ADTs (struct/enum (variant) constructors) and tuples are supported by this refinement.
2101
2102
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 ( ) ) ,
2110
2107
_ => {
2111
2108
return Err ( expr) ;
2112
2109
}
@@ -2122,7 +2119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2122
2119
. filter ( |( _index, ty_arg) | {
2123
2120
relevant_impl_generics
2124
2121
. 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) ) )
2126
2123
} )
2127
2124
. map ( |( index, _ty_arg) | index)
2128
2125
. collect ( ) ;
@@ -2211,9 +2208,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2211
2208
let field_type: Ty < ' tcx > = self . tcx . type_of ( field_def. did ) ;
2212
2209
2213
2210
// 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
+ } )
2217
2214
} )
2218
2215
. collect ( ) ;
2219
2216
@@ -2224,7 +2221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2224
2221
2225
2222
let blameable_field_def: & ty:: FieldDef = blameable_field_defs[ 0 ] ;
2226
2223
2227
- for field in struct_fields. iter ( ) {
2224
+ for field in struct_fields {
2228
2225
if field. ident . as_str ( ) == blameable_field_def. ident ( self . tcx ) . as_str ( ) {
2229
2226
// Blame this field!
2230
2227
return Ok ( field. expr ) ;
@@ -2277,7 +2274,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2277
2274
. variants ( )
2278
2275
. iter ( )
2279
2276
. 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)
2281
2278
} ) ;
2282
2279
2283
2280
let Some ( struct_variant_def) = struct_variant_def else {
@@ -2295,17 +2292,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2295
2292
. collect ( ) ;
2296
2293
2297
2294
// 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).
2298
2297
2299
- let blameable_field_defs: Vec < & ty:: FieldDef > = struct_variant_def
2298
+ let blameable_field_defs: Vec < ( usize , & ty:: FieldDef ) > = struct_variant_def
2300
2299
. fields
2301
2300
. iter ( )
2302
- . filter ( |field_def| {
2301
+ . enumerate ( )
2302
+ . filter ( |( _index, field_def) | {
2303
2303
let field_type: Ty < ' tcx > = self . tcx . type_of ( field_def. did ) ;
2304
2304
2305
2305
// 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
+ } )
2309
2312
} )
2310
2313
. collect ( ) ;
2311
2314
@@ -2314,12 +2317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2314
2317
return Err ( expr) ;
2315
2318
}
2316
2319
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 ] ;
2323
2321
2324
2322
if blameable_field_index < call_ctor_args. len ( ) {
2325
2323
return Ok ( & call_ctor_args[ blameable_field_index] ) ;
@@ -2394,7 +2392,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2394
2392
. iter ( )
2395
2393
. filter ( |field| {
2396
2394
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)
2398
2396
} )
2399
2397
. collect ( ) ;
2400
2398
@@ -2636,7 +2634,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2636
2634
}
2637
2635
}
2638
2636
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 {
2640
2643
let mut walk = ty. walk ( ) ;
2641
2644
while let Some ( arg) = walk. next ( ) {
2642
2645
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>)
2655
2658
}
2656
2659
false
2657
2660
}
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