@@ -15,7 +15,7 @@ use tracing::instrument;
15
15
16
16
use crate :: infer:: at:: ToTrace ;
17
17
use crate :: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
18
- use crate :: traits:: { self , Obligation , ObligationCause , ObligationCtxt , SelectionContext } ;
18
+ use crate :: traits:: { self , Obligation , ObligationCause , ObligationCtxt } ;
19
19
20
20
#[ extension( pub trait InferCtxtExt <' tcx>) ]
21
21
impl < ' tcx > InferCtxt < ' tcx > {
@@ -122,30 +122,36 @@ impl<'tcx> InferCtxt<'tcx> {
122
122
/// - If this returns `Some([errors..])`, then the trait has an impl for
123
123
/// the self type, but some nested obligations do not hold.
124
124
/// - If this returns `None`, no implementation that applies could be found.
125
- ///
126
- /// FIXME(-Znext-solver): Due to the recursive nature of the new solver,
127
- /// this will probably only ever return `Some([])` or `None`.
128
125
fn type_implements_trait_shallow (
129
126
& self ,
130
127
trait_def_id : DefId ,
131
128
ty : Ty < ' tcx > ,
132
129
param_env : ty:: ParamEnv < ' tcx > ,
133
130
) -> Option < Vec < traits:: FulfillmentError < ' tcx > > > {
134
131
self . probe ( |_snapshot| {
135
- let mut selcx = SelectionContext :: new ( self ) ;
136
- match selcx . select ( & Obligation :: new (
132
+ let ocx = ObligationCtxt :: new_with_diagnostics ( self ) ;
133
+ ocx . register_obligation ( Obligation :: new (
137
134
self . tcx ,
138
135
ObligationCause :: dummy ( ) ,
139
136
param_env,
140
137
ty:: TraitRef :: new ( self . tcx , trait_def_id, [ ty] ) ,
141
- ) ) {
142
- Ok ( Some ( selection) ) => {
143
- let ocx = ObligationCtxt :: new_with_diagnostics ( self ) ;
144
- ocx. register_obligations ( selection. nested_obligations ( ) ) ;
145
- Some ( ocx. select_all_or_error ( ) )
138
+ ) ) ;
139
+ let errors = ocx. select_where_possible ( ) ;
140
+ // Find the original predicate in the list of predicates that could definitely not be fulfilled.
141
+ // If it is in that list, then we know this doesn't even shallowly implement the trait.
142
+ // If it is not in that list, it was fulfilled, but there may be nested obligations, which we don't care about here.
143
+ for error in & errors {
144
+ let Some ( trait_clause) = error. obligation . predicate . as_trait_clause ( ) else {
145
+ continue ;
146
+ } ;
147
+ let Some ( bound_ty) = trait_clause. self_ty ( ) . no_bound_vars ( ) else { continue } ;
148
+ if trait_clause. def_id ( ) == trait_def_id
149
+ && ocx. eq ( & ObligationCause :: dummy ( ) , param_env, bound_ty, ty) . is_ok ( )
150
+ {
151
+ return None ;
146
152
}
147
- Ok ( None ) | Err ( _) => None ,
148
153
}
154
+ Some ( errors)
149
155
} )
150
156
}
151
157
}
0 commit comments