@@ -11,26 +11,56 @@ use rustc_trait_selection::traits;
1111
1212use crate :: FnCtxt ;
1313
14+ enum ClauseFlavor {
15+ /// Predicate comes from `predicates_of`.
16+ Where ,
17+ /// Predicate comes from `const_conditions`.
18+ Const ,
19+ }
20+
1421impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
1522 pub ( crate ) fn adjust_fulfillment_error_for_expr_obligation (
1623 & self ,
1724 error : & mut traits:: FulfillmentError < ' tcx > ,
1825 ) -> 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 ,
2334 } ;
2435
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+ }
3464 } ;
3565
3666 let generics = self . tcx . generics_of ( def_id) ;
@@ -39,6 +69,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3969 ty:: ClauseKind :: Trait ( pred) => {
4070 ( pred. trait_ref . args . to_vec ( ) , Some ( pred. self_ty ( ) . into ( ) ) )
4171 }
72+ ty:: ClauseKind :: HostEffect ( pred) => {
73+ ( pred. trait_ref . args . to_vec ( ) , Some ( pred. self_ty ( ) . into ( ) ) )
74+ }
4275 ty:: ClauseKind :: Projection ( pred) => ( pred. projection_term . args . to_vec ( ) , None ) ,
4376 ty:: ClauseKind :: ConstArgHasType ( arg, ty) => ( vec ! [ ty. into( ) , arg. into( ) ] , None ) ,
4477 ty:: ClauseKind :: ConstEvaluatable ( e) => ( vec ! [ e. into( ) ] , None ) ,
@@ -95,6 +128,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
95128 }
96129
97130 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+ }
98176 hir:: Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: Path ( qpath) , span, .. } ) => {
99177 if self . closure_span_overlaps_error ( error, span) {
100178 return false ;
@@ -544,7 +622,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
544622 expr : & ' tcx hir:: Expr < ' tcx > ,
545623 ) -> Result < & ' tcx hir:: Expr < ' tcx > , & ' tcx hir:: Expr < ' tcx > > {
546624 match obligation_cause_code {
547- traits:: ObligationCauseCode :: WhereClauseInExpr ( _, _, _, _) => {
625+ traits:: ObligationCauseCode :: WhereClauseInExpr ( _, _, _, _)
626+ | ObligationCauseCode :: HostEffectInExpr ( ..) => {
548627 // This is the "root"; we assume that the `expr` is already pointing here.
549628 // Therefore, we return `Ok` so that this `expr` can be refined further.
550629 Ok ( expr)
0 commit comments