@@ -4,7 +4,7 @@ use rustc_hir::def::Res;
4
4
use rustc_hir:: def_id:: DefId ;
5
5
use rustc_infer:: traits:: ObligationCauseCode ;
6
6
use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitor } ;
7
- use rustc_span:: { self , Span } ;
7
+ use rustc_span:: { self , symbol :: kw , Span } ;
8
8
use rustc_trait_selection:: traits;
9
9
10
10
use std:: ops:: ControlFlow ;
@@ -25,17 +25,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25
25
26
26
let generics = self . tcx . generics_of ( def_id) ;
27
27
let predicate_substs = match unsubstituted_pred. kind ( ) . skip_binder ( ) {
28
- ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( pred) ) => pred. trait_ref . substs ,
29
- ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( pred) ) => pred. projection_ty . substs ,
30
- _ => ty:: List :: empty ( ) ,
28
+ ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( pred) ) => pred. trait_ref . substs . to_vec ( ) ,
29
+ ty:: PredicateKind :: Clause ( ty:: Clause :: Projection ( pred) ) => {
30
+ pred. projection_ty . substs . to_vec ( )
31
+ }
32
+ ty:: PredicateKind :: Clause ( ty:: Clause :: ConstArgHasType ( arg, ty) ) => {
33
+ vec ! [ ty. into( ) , arg. into( ) ]
34
+ }
35
+ ty:: PredicateKind :: ConstEvaluatable ( e) => vec ! [ e. into( ) ] ,
36
+ _ => return false ,
31
37
} ;
32
38
33
- let find_param_matching = |matches : & dyn Fn ( & ty:: ParamTy ) -> bool | {
34
- predicate_substs. types ( ) . find_map ( |ty | {
35
- ty . walk ( ) . find_map ( |arg| {
39
+ let find_param_matching = |matches : & dyn Fn ( ty:: ParamTerm ) -> bool | {
40
+ predicate_substs. iter ( ) . find_map ( |arg | {
41
+ arg . walk ( ) . find_map ( |arg| {
36
42
if let ty:: GenericArgKind :: Type ( ty) = arg. unpack ( )
37
- && let ty:: Param ( param_ty) = ty. kind ( )
38
- && matches ( param_ty)
43
+ && let ty:: Param ( param_ty) = * ty. kind ( )
44
+ && matches ( ty:: ParamTerm :: Ty ( param_ty) )
45
+ {
46
+ Some ( arg)
47
+ } else if let ty:: GenericArgKind :: Const ( ct) = arg. unpack ( )
48
+ && let ty:: ConstKind :: Param ( param_ct) = ct. kind ( )
49
+ && matches ( ty:: ParamTerm :: Const ( param_ct) )
39
50
{
40
51
Some ( arg)
41
52
} else {
@@ -47,21 +58,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
47
58
48
59
// Prefer generics that are local to the fn item, since these are likely
49
60
// to be the cause of the unsatisfied predicate.
50
- let mut param_to_point_at = find_param_matching ( & |param_ty | {
51
- self . tcx . parent ( generics. type_param ( param_ty , self . tcx ) . def_id ) == def_id
61
+ let mut param_to_point_at = find_param_matching ( & |param_term | {
62
+ self . tcx . parent ( generics. param_at ( param_term . index ( ) , self . tcx ) . def_id ) == def_id
52
63
} ) ;
53
64
// Fall back to generic that isn't local to the fn item. This will come
54
65
// from a trait or impl, for example.
55
- let mut fallback_param_to_point_at = find_param_matching ( & |param_ty | {
56
- self . tcx . parent ( generics. type_param ( param_ty , self . tcx ) . def_id ) != def_id
57
- && param_ty . name != rustc_span :: symbol :: kw:: SelfUpper
66
+ let mut fallback_param_to_point_at = find_param_matching ( & |param_term | {
67
+ self . tcx . parent ( generics. param_at ( param_term . index ( ) , self . tcx ) . def_id ) != def_id
68
+ && ! matches ! ( param_term , ty :: ParamTerm :: Ty ( ty ) if ty . name == kw:: SelfUpper )
58
69
} ) ;
59
70
// Finally, the `Self` parameter is possibly the reason that the predicate
60
71
// is unsatisfied. This is less likely to be true for methods, because
61
72
// method probe means that we already kinda check that the predicates due
62
73
// to the `Self` type are true.
63
- let mut self_param_to_point_at =
64
- find_param_matching ( & |param_ty| param_ty. name == rustc_span:: symbol:: kw:: SelfUpper ) ;
74
+ let mut self_param_to_point_at = find_param_matching (
75
+ & |param_term| matches ! ( param_term, ty:: ParamTerm :: Ty ( ty) if ty. name == kw:: SelfUpper ) ,
76
+ ) ;
65
77
66
78
// Finally, for ambiguity-related errors, we actually want to look
67
79
// for a parameter that is the source of the inference type left
@@ -225,14 +237,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
225
237
. own_substs ( ty:: InternalSubsts :: identity_for_item ( self . tcx , def_id) ) ;
226
238
let Some ( ( index, _) ) = own_substs
227
239
. iter ( )
228
- . filter ( |arg| matches ! ( arg. unpack( ) , ty:: GenericArgKind :: Type ( _) ) )
229
240
. enumerate ( )
230
241
. find ( |( _, arg) | * * arg == param_to_point_at) else { return false } ;
231
242
let Some ( arg) = segment
232
243
. args ( )
233
244
. args
234
245
. iter ( )
235
- . filter ( |arg| matches ! ( arg, hir:: GenericArg :: Type ( _) ) )
236
246
. nth ( index) else { return false ; } ;
237
247
error. obligation . cause . span = arg
238
248
. span ( )
0 commit comments