@@ -9,7 +9,6 @@ use rustc_infer::traits::{Obligation, ObligationCause};
9
9
use rustc_macros:: extension;
10
10
use rustc_middle:: traits:: DefiningAnchor ;
11
11
use rustc_middle:: ty:: visit:: TypeVisitableExt ;
12
- use rustc_middle:: ty:: RegionVid ;
13
12
use rustc_middle:: ty:: { self , OpaqueHiddenType , OpaqueTypeKey , Ty , TyCtxt , TypeFoldable } ;
14
13
use rustc_middle:: ty:: { GenericArgKind , GenericArgs } ;
15
14
use rustc_span:: Span ;
@@ -23,73 +22,6 @@ use crate::universal_regions::RegionClassification;
23
22
use super :: RegionInferenceContext ;
24
23
25
24
impl < ' tcx > RegionInferenceContext < ' tcx > {
26
- fn universal_name ( & self , vid : ty:: RegionVid ) -> Option < ty:: Region < ' tcx > > {
27
- let scc = self . constraint_sccs . scc ( vid) ;
28
- self . scc_values
29
- . universal_regions_outlived_by ( scc)
30
- . find_map ( |lb| self . eval_equal ( vid, lb) . then_some ( self . definitions [ lb] . external_name ?) )
31
- }
32
-
33
- fn generic_arg_to_region ( & self , arg : ty:: GenericArg < ' tcx > ) -> Option < RegionVid > {
34
- let region = arg. as_region ( ) ?;
35
-
36
- if let ty:: RePlaceholder ( ..) = region. kind ( ) {
37
- None
38
- } else {
39
- Some ( self . to_region_vid ( region) )
40
- }
41
- }
42
-
43
- /// Check that all opaque types have the same region parameters if they have the same
44
- /// non-region parameters. This is necessary because within the new solver we perform various query operations
45
- /// modulo regions, and thus could unsoundly select some impls that don't hold.
46
- fn check_unique (
47
- & self ,
48
- infcx : & InferCtxt < ' tcx > ,
49
- opaque_ty_decls : & FxIndexMap < OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > > ,
50
- ) {
51
- for ( i, ( a, a_ty) ) in opaque_ty_decls. iter ( ) . enumerate ( ) {
52
- for ( b, b_ty) in opaque_ty_decls. iter ( ) . skip ( i + 1 ) {
53
- if a. def_id != b. def_id {
54
- continue ;
55
- }
56
- // Non-lifetime params differ -> ok
57
- if infcx. tcx . erase_regions ( a. args ) != infcx. tcx . erase_regions ( b. args ) {
58
- continue ;
59
- }
60
- trace ! ( ?a, ?b) ;
61
- for ( a, b) in a. args . iter ( ) . zip ( b. args ) {
62
- trace ! ( ?a, ?b) ;
63
- let Some ( r1) = self . generic_arg_to_region ( a) else {
64
- continue ;
65
- } ;
66
- let Some ( r2) = self . generic_arg_to_region ( b) else {
67
- continue ;
68
- } ;
69
- if self . eval_equal ( r1, r2) {
70
- continue ;
71
- }
72
-
73
- // Ignore non-universal regions because they result in an error eventually.
74
- // FIXME(aliemjay): This logic will be rewritten in a later commit.
75
- let Some ( r1) = self . universal_name ( r1) else {
76
- continue ;
77
- } ;
78
- let Some ( r2) = self . universal_name ( r2) else {
79
- continue ;
80
- } ;
81
-
82
- infcx. dcx ( ) . emit_err ( LifetimeMismatchOpaqueParam {
83
- arg : r1. into ( ) ,
84
- prev : r2. into ( ) ,
85
- span : a_ty. span ,
86
- prev_span : b_ty. span ,
87
- } ) ;
88
- }
89
- }
90
- }
91
- }
92
-
93
25
/// Resolve any opaque types that were encountered while borrow checking
94
26
/// this item. This is then used to get the type in the `type_of` query.
95
27
///
@@ -139,9 +71,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
139
71
infcx : & InferCtxt < ' tcx > ,
140
72
opaque_ty_decls : FxIndexMap < OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > > ,
141
73
) -> FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > {
142
- self . check_unique ( infcx, & opaque_ty_decls) ;
143
-
144
74
let mut result: FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > = FxIndexMap :: default ( ) ;
75
+ let mut decls_modulo_regions: FxIndexMap < OpaqueTypeKey < ' tcx > , ( OpaqueTypeKey < ' tcx > , Span ) > =
76
+ FxIndexMap :: default ( ) ;
145
77
146
78
for ( opaque_type_key, concrete_type) in opaque_ty_decls {
147
79
debug ! ( ?opaque_type_key, ?concrete_type) ;
@@ -228,6 +160,29 @@ impl<'tcx> RegionInferenceContext<'tcx> {
228
160
OpaqueHiddenType { ty, span : concrete_type. span } ,
229
161
) ;
230
162
}
163
+
164
+ // Check that all opaque types have the same region parameters if they have the same
165
+ // non-region parameters. This is necessary because within the new solver we perform
166
+ // various query operations modulo regions, and thus could unsoundly select some impls
167
+ // that don't hold.
168
+ if !ty. references_error ( )
169
+ && let Some ( ( prev_decl_key, prev_span) ) = decls_modulo_regions. insert (
170
+ infcx. tcx . erase_regions ( opaque_type_key) ,
171
+ ( opaque_type_key, concrete_type. span ) ,
172
+ )
173
+ && let Some ( ( arg1, arg2) ) = std:: iter:: zip (
174
+ prev_decl_key. iter_captured_args ( infcx. tcx ) . map ( |( _, arg) | arg) ,
175
+ opaque_type_key. iter_captured_args ( infcx. tcx ) . map ( |( _, arg) | arg) ,
176
+ )
177
+ . find ( |( arg1, arg2) | arg1 != arg2)
178
+ {
179
+ infcx. dcx ( ) . emit_err ( LifetimeMismatchOpaqueParam {
180
+ arg : arg1,
181
+ prev : arg2,
182
+ span : prev_span,
183
+ prev_span : concrete_type. span ,
184
+ } ) ;
185
+ }
231
186
}
232
187
result
233
188
}
0 commit comments