@@ -13,11 +13,68 @@ use rustc_span::Span;
13
13
use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
14
14
use rustc_trait_selection:: traits:: ObligationCtxt ;
15
15
16
+ use crate :: session_diagnostics:: LifetimeMismatchOpaqueParam ;
16
17
use crate :: session_diagnostics:: NonGenericOpaqueTypeParam ;
17
18
18
19
use super :: RegionInferenceContext ;
19
20
20
21
impl < ' tcx > RegionInferenceContext < ' tcx > {
22
+ fn universal_name ( & self , vid : ty:: RegionVid ) -> Option < ty:: Region < ' tcx > > {
23
+ let scc = self . constraint_sccs . scc ( vid) ;
24
+ self . scc_values
25
+ . universal_regions_outlived_by ( scc)
26
+ . find_map ( |lb| self . eval_equal ( vid, lb) . then_some ( self . definitions [ lb] . external_name ?) )
27
+ }
28
+
29
+ fn gen_arg_to_name ( & self , arg : ty:: GenericArg < ' tcx > ) -> Option < ty:: Region < ' tcx > > {
30
+ let region = arg. as_region ( ) ?;
31
+
32
+ if let ty:: RePlaceholder ( ..) = region. kind ( ) {
33
+ return None ;
34
+ }
35
+ self . universal_name ( self . to_region_vid ( region) )
36
+ }
37
+
38
+ /// Check that all opaque types have the same region parameters if they have the same
39
+ /// non-region parameters. This is necessary because within the new solver we perform various query operations
40
+ /// modulo regions, and thus could unsoundly select some impls that don't hold.
41
+ fn check_unique (
42
+ & self ,
43
+ infcx : & InferCtxt < ' tcx > ,
44
+ opaque_ty_decls : & FxIndexMap < OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > > ,
45
+ ) {
46
+ for ( i, ( a, a_ty) ) in opaque_ty_decls. iter ( ) . enumerate ( ) {
47
+ for ( b, b_ty) in opaque_ty_decls. iter ( ) . skip ( i + 1 ) {
48
+ if a. def_id != b. def_id {
49
+ continue ;
50
+ }
51
+ // Non-lifetime params differ -> ok
52
+ if infcx. tcx . erase_regions ( a. args ) != infcx. tcx . erase_regions ( b. args ) {
53
+ continue ;
54
+ }
55
+ trace ! ( ?a, ?b) ;
56
+ for ( a, b) in a. args . iter ( ) . zip ( b. args ) {
57
+ if a. as_region ( ) . is_none ( ) {
58
+ break ;
59
+ }
60
+ let a = self . gen_arg_to_name ( a) . unwrap ( ) ;
61
+ let b = self . gen_arg_to_name ( b) . unwrap ( ) ;
62
+ trace ! ( ?a, ?b) ;
63
+ if a == b {
64
+ continue ;
65
+ }
66
+
67
+ infcx. tcx . sess . emit_err ( LifetimeMismatchOpaqueParam {
68
+ arg : a. into ( ) ,
69
+ prev : b. into ( ) ,
70
+ span : a_ty. span ,
71
+ prev_span : b_ty. span ,
72
+ } ) ;
73
+ }
74
+ }
75
+ }
76
+ }
77
+
21
78
/// Resolve any opaque types that were encountered while borrow checking
22
79
/// this item. This is then used to get the type in the `type_of` query.
23
80
///
@@ -63,6 +120,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
63
120
infcx : & InferCtxt < ' tcx > ,
64
121
opaque_ty_decls : FxIndexMap < OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > > ,
65
122
) -> FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > {
123
+ self . check_unique ( infcx, & opaque_ty_decls) ;
124
+
66
125
let mut result: FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > = FxIndexMap :: default ( ) ;
67
126
68
127
let member_constraints: FxIndexMap < _ , _ > = self
@@ -78,13 +137,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
78
137
79
138
let mut subst_regions = vec ! [ self . universal_regions. fr_static] ;
80
139
81
- let to_universal_region = |vid, subst_regions : & mut Vec < _ > | {
82
- trace ! ( ?vid) ;
83
- let scc = self . constraint_sccs . scc ( vid) ;
84
- trace ! ( ?scc) ;
85
- match self . scc_values . universal_regions_outlived_by ( scc) . find_map ( |lb| {
86
- self . eval_equal ( vid, lb) . then_some ( self . definitions [ lb] . external_name ?)
87
- } ) {
140
+ let to_universal_region =
141
+ |vid, subst_regions : & mut Vec < _ > | match self . universal_name ( vid) {
88
142
Some ( region) => {
89
143
let vid = self . universal_regions . to_region_vid ( region) ;
90
144
subst_regions. push ( vid) ;
@@ -98,8 +152,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
98
152
"opaque type with non-universal region args" ,
99
153
)
100
154
}
101
- }
102
- } ;
155
+ } ;
103
156
104
157
// Start by inserting universal regions from the member_constraint choice regions.
105
158
// This will ensure they get precedence when folding the regions in the concrete type.
0 commit comments