1
1
use rustc_hir as hir;
2
- use rustc_infer:: infer:: { DefineOpaqueTypes , InferOk , TyCtxtInferExt } ;
3
- use rustc_infer:: traits;
4
- use rustc_middle:: ty:: { self , TypingMode , Upcast } ;
2
+ use rustc_infer:: infer:: TyCtxtInferExt ;
3
+ use rustc_infer:: traits:: ObligationCause ;
4
+ use rustc_middle:: ty:: { self , TypingMode } ;
5
5
use rustc_span:: DUMMY_SP ;
6
6
use rustc_span:: def_id:: DefId ;
7
- use rustc_trait_selection:: traits:: query :: evaluate_obligation :: InferCtxtExt ;
7
+ use rustc_trait_selection:: traits;
8
8
use thin_vec:: ThinVec ;
9
- use tracing:: { debug, instrument, trace } ;
9
+ use tracing:: { debug, instrument} ;
10
10
11
11
use crate :: clean;
12
12
use crate :: clean:: {
@@ -22,6 +22,9 @@ pub(crate) fn synthesize_blanket_impls(
22
22
let tcx = cx. tcx ;
23
23
let ty = tcx. type_of ( item_def_id) ;
24
24
25
+ let infcx =
26
+ tcx. infer_ctxt ( ) . with_next_trait_solver ( true ) . build ( TypingMode :: non_body_analysis ( ) ) ;
27
+
25
28
let mut blanket_impls = Vec :: new ( ) ;
26
29
for trait_def_id in tcx. visible_traits ( ) {
27
30
if !cx. cache . effective_visibilities . is_reachable ( tcx, trait_def_id)
@@ -31,53 +34,37 @@ pub(crate) fn synthesize_blanket_impls(
31
34
}
32
35
// NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
33
36
let trait_impls = tcx. trait_impls_of ( trait_def_id) ;
34
- ' blanket_impls: for & impl_def_id in trait_impls. blanket_impls ( ) {
35
- trace ! ( "considering impl `{impl_def_id:?}` for trait `{trait_def_id:?}`" ) ;
36
-
37
+ for & impl_def_id in trait_impls. blanket_impls ( ) {
37
38
let trait_ref = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) ;
38
- if !matches ! ( trait_ref. skip_binder( ) . self_ty( ) . kind( ) , ty:: Param ( _) ) {
39
- continue ;
40
- }
41
- let infcx = tcx. infer_ctxt ( ) . build ( TypingMode :: non_body_analysis ( ) ) ;
39
+
40
+ let ty:: Param ( _) = trait_ref. skip_binder ( ) . self_ty ( ) . kind ( ) else { continue } ;
41
+
42
+ let ocx = traits:: ObligationCtxt :: new ( & infcx) ;
43
+
42
44
let args = infcx. fresh_args_for_item ( DUMMY_SP , item_def_id) ;
43
45
let impl_ty = ty. instantiate ( tcx, args) ;
44
46
let param_env = ty:: ParamEnv :: empty ( ) ;
47
+ let cause = ObligationCause :: dummy ( ) ;
45
48
46
49
let impl_args = infcx. fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
47
50
let impl_trait_ref = trait_ref. instantiate ( tcx, impl_args) ;
48
51
49
52
// Require the type the impl is implemented on to match
50
53
// our type, and ignore the impl if there was a mismatch.
51
- let Ok ( eq_result) = infcx. at ( & traits:: ObligationCause :: dummy ( ) , param_env) . eq (
52
- DefineOpaqueTypes :: Yes ,
53
- impl_trait_ref. self_ty ( ) ,
54
- impl_ty,
55
- ) else {
54
+ if ocx. eq ( & cause, param_env, impl_trait_ref. self_ty ( ) , impl_ty) . is_err ( ) {
56
55
continue ;
57
- } ;
58
- let InferOk { value : ( ) , obligations } = eq_result;
59
- // FIXME(eddyb) ignoring `obligations` might cause false positives.
60
- drop ( obligations) ;
56
+ }
57
+
58
+ ocx. register_obligations ( traits:: predicates_for_generics (
59
+ |_, _| cause. clone ( ) ,
60
+ param_env,
61
+ tcx. predicates_of ( impl_def_id) . instantiate ( tcx, impl_args) ,
62
+ ) ) ;
61
63
62
- let predicates = tcx
63
- . predicates_of ( impl_def_id)
64
- . instantiate ( tcx, impl_args)
65
- . predicates
66
- . into_iter ( )
67
- . chain ( Some ( impl_trait_ref. upcast ( tcx) ) ) ;
68
- for predicate in predicates {
69
- let obligation = traits:: Obligation :: new (
70
- tcx,
71
- traits:: ObligationCause :: dummy ( ) ,
72
- param_env,
73
- predicate,
74
- ) ;
75
- match infcx. evaluate_obligation ( & obligation) {
76
- Ok ( eval_result) if eval_result. may_apply ( ) => { }
77
- Err ( traits:: OverflowError :: Canonical ) => { }
78
- _ => continue ' blanket_impls,
79
- }
64
+ if !ocx. select_where_possible ( ) . is_empty ( ) {
65
+ continue ;
80
66
}
67
+
81
68
debug ! ( "found applicable impl for trait ref {trait_ref:?}" ) ;
82
69
83
70
cx. generated_synthetics . insert ( ( ty. skip_binder ( ) , trait_def_id) ) ;
0 commit comments