@@ -11,26 +11,56 @@ use rustc_trait_selection::traits;
11
11
12
12
use crate :: FnCtxt ;
13
13
14
+ enum ClauseFlavor {
15
+ /// Predicate comes from `predicates_of`.
16
+ Where ,
17
+ /// Predicate comes from `const_conditions`.
18
+ Const ,
19
+ }
20
+
14
21
impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
15
22
pub ( crate ) fn adjust_fulfillment_error_for_expr_obligation (
16
23
& self ,
17
24
error : & mut traits:: FulfillmentError < ' tcx > ,
18
25
) -> bool {
19
- let ObligationCauseCode :: WhereClauseInExpr ( def_id, _, hir_id, idx) =
20
- * error. obligation . cause . code ( ) . peel_derives ( )
21
- else {
22
- return false ;
26
+ let ( def_id, hir_id, idx, flavor) = match * error. obligation . cause . code ( ) . peel_derives ( ) {
27
+ ObligationCauseCode :: WhereClauseInExpr ( def_id, _, hir_id, idx) => {
28
+ ( def_id, hir_id, idx, ClauseFlavor :: Where )
29
+ }
30
+ ObligationCauseCode :: HostEffectInExpr ( def_id, _, hir_id, idx) => {
31
+ ( def_id, hir_id, idx, ClauseFlavor :: Const )
32
+ }
33
+ _ => return false ,
23
34
} ;
24
35
25
- let Some ( uninstantiated_pred) = self
26
- . tcx
27
- . predicates_of ( def_id)
28
- . instantiate_identity ( self . tcx )
29
- . predicates
30
- . into_iter ( )
31
- . nth ( idx)
32
- else {
33
- return false ;
36
+ let uninstantiated_pred = match flavor {
37
+ ClauseFlavor :: Where => {
38
+ if let Some ( pred) = self
39
+ . tcx
40
+ . predicates_of ( def_id)
41
+ . instantiate_identity ( self . tcx )
42
+ . predicates
43
+ . into_iter ( )
44
+ . nth ( idx)
45
+ {
46
+ pred
47
+ } else {
48
+ return false ;
49
+ }
50
+ }
51
+ ClauseFlavor :: Const => {
52
+ if let Some ( ( pred, _) ) = self
53
+ . tcx
54
+ . const_conditions ( def_id)
55
+ . instantiate_identity ( self . tcx )
56
+ . into_iter ( )
57
+ . nth ( idx)
58
+ {
59
+ pred. to_host_effect_clause ( self . tcx , ty:: BoundConstness :: Maybe )
60
+ } else {
61
+ return false ;
62
+ }
63
+ }
34
64
} ;
35
65
36
66
let generics = self . tcx . generics_of ( def_id) ;
@@ -39,6 +69,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
39
69
ty:: ClauseKind :: Trait ( pred) => {
40
70
( pred. trait_ref . args . to_vec ( ) , Some ( pred. self_ty ( ) . into ( ) ) )
41
71
}
72
+ ty:: ClauseKind :: HostEffect ( pred) => {
73
+ ( pred. trait_ref . args . to_vec ( ) , Some ( pred. self_ty ( ) . into ( ) ) )
74
+ }
42
75
ty:: ClauseKind :: Projection ( pred) => ( pred. projection_term . args . to_vec ( ) , None ) ,
43
76
ty:: ClauseKind :: ConstArgHasType ( arg, ty) => ( vec ! [ ty. into( ) , arg. into( ) ] , None ) ,
44
77
ty:: ClauseKind :: ConstEvaluatable ( e) => ( vec ! [ e. into( ) ] , None ) ,
@@ -95,6 +128,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
95
128
}
96
129
97
130
match self . tcx . hir_node ( hir_id) {
131
+ hir:: Node :: Expr ( & hir:: Expr {
132
+ kind :
133
+ hir:: ExprKind :: Call (
134
+ hir:: Expr { kind : hir:: ExprKind :: Path ( qpath) , span : callee_span, .. } ,
135
+ args,
136
+ ) ,
137
+ span,
138
+ ..
139
+ } ) => {
140
+ if self . closure_span_overlaps_error ( error, span) {
141
+ return false ;
142
+ }
143
+
144
+ if let Some ( param) = predicate_self_type_to_point_at
145
+ && self . point_at_path_if_possible ( error, def_id, param, & qpath)
146
+ {
147
+ return true ;
148
+ }
149
+
150
+ for param in [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
151
+ . into_iter ( )
152
+ . flatten ( )
153
+ {
154
+ if self . blame_specific_arg_if_possible (
155
+ error,
156
+ def_id,
157
+ param,
158
+ hir_id,
159
+ * callee_span,
160
+ None ,
161
+ args,
162
+ ) {
163
+ return true ;
164
+ }
165
+ }
166
+
167
+ for param in [ param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
168
+ . into_iter ( )
169
+ . flatten ( )
170
+ {
171
+ if self . point_at_path_if_possible ( error, def_id, param, & qpath) {
172
+ return true ;
173
+ }
174
+ }
175
+ }
98
176
hir:: Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: Path ( qpath) , span, .. } ) => {
99
177
if self . closure_span_overlaps_error ( error, span) {
100
178
return false ;
@@ -544,7 +622,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
544
622
expr : & ' tcx hir:: Expr < ' tcx > ,
545
623
) -> Result < & ' tcx hir:: Expr < ' tcx > , & ' tcx hir:: Expr < ' tcx > > {
546
624
match obligation_cause_code {
547
- traits:: ObligationCauseCode :: WhereClauseInExpr ( _, _, _, _) => {
625
+ traits:: ObligationCauseCode :: WhereClauseInExpr ( _, _, _, _)
626
+ | ObligationCauseCode :: HostEffectInExpr ( ..) => {
548
627
// This is the "root"; we assume that the `expr` is already pointing here.
549
628
// Therefore, we return `Ok` so that this `expr` can be refined further.
550
629
Ok ( expr)
0 commit comments