@@ -120,6 +120,48 @@ pub fn overlapping_impls(
120
120
Some ( overlap ( selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode) . unwrap ( ) )
121
121
}
122
122
123
+ /// Given an impl_def_id that "positively" implement a trait, check if the "negative" holds.
124
+ pub fn negative_impl_holds ( tcx : TyCtxt < ' _ > , impl_def_id : DefId , overlap_mode : OverlapMode ) -> bool {
125
+ debug ! ( "negative_impl_holds(impl1_header={:?}, overlap_mode={:?})" , impl_def_id, overlap_mode) ;
126
+ // `for<T> (Vec<u32>, T): Trait`
127
+ let header = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) ;
128
+
129
+ let infcx = tcx
130
+ . infer_ctxt ( )
131
+ . with_opaque_type_inference ( DefiningAnchor :: Bubble )
132
+ . intercrate ( true )
133
+ . build ( ) ;
134
+
135
+ // `[?t]`
136
+ let infer_substs = infcx. fresh_substs_for_item ( DUMMY_SP , impl_def_id) ;
137
+
138
+ // `(Vec<u32>, ?t): Trait`
139
+ let trait_ref = header. subst ( tcx, infer_substs) ;
140
+
141
+ // `(Vec<u32>, ?t): !Trait`
142
+ let trait_pred = tcx. mk_predicate ( ty:: Binder :: dummy ( ty:: PredicateKind :: Clause (
143
+ ty:: Clause :: Trait ( ty:: TraitPredicate {
144
+ trait_ref,
145
+ constness : ty:: BoundConstness :: NotConst ,
146
+ polarity : ty:: ImplPolarity :: Negative ,
147
+ } ) ,
148
+ ) ) ) ;
149
+
150
+ // Ideally we would use param_env(impl_def_id) but that's unsound today.
151
+ let param_env = ty:: ParamEnv :: empty ( ) ;
152
+
153
+ let selcx = & mut SelectionContext :: new ( & infcx) ;
154
+ selcx
155
+ . evaluate_root_obligation ( & Obligation :: new (
156
+ tcx,
157
+ ObligationCause :: dummy ( ) ,
158
+ param_env,
159
+ trait_pred,
160
+ ) )
161
+ . expect ( "Overflow should be caught earlier in standard query mode" )
162
+ . must_apply_modulo_regions ( )
163
+ }
164
+
123
165
fn with_fresh_ty_vars < ' cx , ' tcx > (
124
166
selcx : & mut SelectionContext < ' cx , ' tcx > ,
125
167
param_env : ty:: ParamEnv < ' tcx > ,
0 commit comments