@@ -26,7 +26,7 @@ use rustc_middle::mir::*;
26
26
use rustc_middle:: ty:: adjustment:: PointerCast ;
27
27
use rustc_middle:: ty:: cast:: CastTy ;
28
28
use rustc_middle:: ty:: fold:: TypeFoldable ;
29
- use rustc_middle:: ty:: subst:: { GenericArgKind , Subst , SubstsRef , UserSubsts } ;
29
+ use rustc_middle:: ty:: subst:: { GenericArgKind , SubstsRef , UserSubsts } ;
30
30
use rustc_middle:: ty:: {
31
31
self , CanonicalUserTypeAnnotation , CanonicalUserTypeAnnotations , OpaqueTypeKey , RegionVid ,
32
32
ToPredicate , Ty , TyCtxt , UserType , UserTypeAnnotationIndex , WithConstness ,
@@ -60,7 +60,6 @@ use crate::borrow_check::{
60
60
LivenessValues , PlaceholderIndex , PlaceholderIndices , RegionValueElements ,
61
61
} ,
62
62
region_infer:: { ClosureRegionRequirementsExt , TypeTest } ,
63
- renumber,
64
63
type_check:: free_region_relations:: { CreateResult , UniversalRegionRelations } ,
65
64
universal_regions:: { DefiningTy , UniversalRegions } ,
66
65
Upvar ,
@@ -180,7 +179,66 @@ pub(crate) fn type_check<'mir, 'tcx>(
180
179
liveness:: generate ( & mut cx, body, elements, flow_inits, move_data, location_table) ;
181
180
182
181
translate_outlives_facts ( & mut cx) ;
183
- cx. opaque_type_values
182
+ let mut opaque_type_values = cx. opaque_type_values ;
183
+
184
+ for ( _, revealed_ty) in & mut opaque_type_values {
185
+ // FIXME(oli-obk): Instead of looping, implement a visitor like
186
+ // FullTypeResolver. We can't use FullTypeResolver here, as that will
187
+ // resolve lifetimes lexically, which it can't because we didn't do old
188
+ // borrowck stuff. We want to use MIR borrowck information instead.
189
+
190
+ while revealed_ty. has_infer_types_or_consts ( ) {
191
+ let prev = * revealed_ty;
192
+ trace ! ( prev=?prev. kind( ) ) ;
193
+ let type_resolved = infcx. shallow_resolve ( prev) ;
194
+ trace ! ( type_resolved=?type_resolved. kind( ) ) ;
195
+ if prev == type_resolved {
196
+ infcx. tcx . sess . delay_span_bug (
197
+ body. span ,
198
+ & format ! ( "could not resolve {:#?}" , type_resolved. kind( ) ) ,
199
+ ) ;
200
+ * revealed_ty = infcx. tcx . ty_error ( ) ;
201
+ break ;
202
+ }
203
+ * revealed_ty = type_resolved;
204
+ }
205
+ }
206
+
207
+ opaque_type_values. retain ( |( opaque_type_key, resolved_ty) | {
208
+ let concrete_is_opaque = if let ty:: Opaque ( def_id, _) = resolved_ty. kind ( ) {
209
+ * def_id == opaque_type_key. def_id
210
+ } else {
211
+ false
212
+ } ;
213
+
214
+ if concrete_is_opaque {
215
+ // We're using an opaque `impl Trait` type without
216
+ // 'revealing' it. For example, code like this:
217
+ //
218
+ // type Foo = impl Debug;
219
+ // fn foo1() -> Foo { ... }
220
+ // fn foo2() -> Foo { foo1() }
221
+ //
222
+ // In `foo2`, we're not revealing the type of `Foo` - we're
223
+ // just treating it as the opaque type.
224
+ //
225
+ // When this occurs, we do *not* want to try to equate
226
+ // the concrete type with the underlying defining type
227
+ // of the opaque type - this will always fail, since
228
+ // the defining type of an opaque type is always
229
+ // some other type (e.g. not itself)
230
+ // Essentially, none of the normal obligations apply here -
231
+ // we're just passing around some unknown opaque type,
232
+ // without actually looking at the underlying type it
233
+ // gets 'revealed' into
234
+ debug ! (
235
+ "eq_opaque_type_and_type: non-defining use of {:?}" ,
236
+ opaque_type_key. def_id,
237
+ ) ;
238
+ }
239
+ !concrete_is_opaque
240
+ } ) ;
241
+ opaque_type_values
184
242
} ,
185
243
) ;
186
244
@@ -1240,13 +1298,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1240
1298
}
1241
1299
1242
1300
let infcx = self . infcx ;
1243
- let tcx = infcx. tcx ;
1244
1301
let param_env = self . param_env ;
1245
1302
let body = self . body ;
1246
1303
let mir_def_id = body. source . def_id ( ) . expect_local ( ) ;
1247
1304
1248
- // the "concrete opaque types" maps
1249
- let concrete_opaque_types = & tcx. typeck ( mir_def_id) . concrete_opaque_types ;
1250
1305
let mut opaque_type_values = VecMap :: new ( ) ;
1251
1306
1252
1307
debug ! ( "eq_opaque_type_and_type: mir_def_id={:?}" , mir_def_id) ;
@@ -1296,88 +1351,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1296
1351
. eq ( output_ty, revealed_ty) ?,
1297
1352
) ;
1298
1353
1299
- // For each opaque type `Foo<T>` inferred by this value, we want to equate
1300
- // the inference variable `?T` with the revealed type that was computed
1301
- // earlier by type check.
1302
1354
for & ( opaque_type_key, opaque_decl) in & opaque_type_map {
1303
- let resolved_ty = infcx. resolve_vars_if_possible ( opaque_decl. concrete_ty ) ;
1304
- let concrete_is_opaque = if let ty:: Opaque ( def_id, _) = resolved_ty. kind ( ) {
1305
- * def_id == opaque_type_key. def_id
1306
- } else {
1307
- false
1308
- } ;
1309
-
1310
- // The revealed type computed by the earlier phase of type check.
1311
- // In our example, this would be `(U, u32)`. Note that this references
1312
- // the type parameter `U` from the definition of `Foo`.
1313
- let concrete_ty = match concrete_opaque_types
1314
- . get_by ( |( key, _) | key. def_id == opaque_type_key. def_id )
1315
- {
1316
- None => {
1317
- if !concrete_is_opaque {
1318
- tcx. sess . delay_span_bug (
1319
- body. span ,
1320
- & format ! (
1321
- "Non-defining use of {:?} with revealed type" ,
1322
- opaque_type_key. def_id,
1323
- ) ,
1324
- ) ;
1325
- }
1326
- continue ;
1327
- }
1328
- Some ( concrete_ty) => concrete_ty,
1329
- } ;
1330
- debug ! ( "concrete_ty = {:?}" , concrete_ty) ;
1331
-
1332
- // Apply the substitution, in this case `[U -> T]`, so that the
1333
- // concrete type becomes `Foo<(T, u32)>`
1334
- let subst_opaque_defn_ty = concrete_ty. subst ( tcx, opaque_type_key. substs ) ;
1335
-
1336
- // "Renumber" this, meaning that we replace all the regions
1337
- // with fresh inference variables. Not relevant to our example.
1338
- let renumbered_opaque_defn_ty =
1339
- renumber:: renumber_regions ( infcx, subst_opaque_defn_ty) ;
1340
-
1341
- debug ! (
1342
- "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}" ,
1343
- concrete_ty, resolved_ty, renumbered_opaque_defn_ty,
1344
- ) ;
1345
-
1346
- if !concrete_is_opaque {
1347
- // Equate the instantiated opaque type `opaque_decl.concrete_ty` (`?T`,
1348
- // in our example) with the renumbered version that we took from
1349
- // the type check results (`Foo<(T, u32)>`).
1350
- obligations. add (
1351
- infcx
1352
- . at ( & ObligationCause :: dummy ( ) , param_env)
1353
- . eq ( opaque_decl. concrete_ty , renumbered_opaque_defn_ty) ?,
1354
- ) ;
1355
- opaque_type_values. insert ( opaque_type_key, renumbered_opaque_defn_ty) ;
1356
- } else {
1357
- // We're using an opaque `impl Trait` type without
1358
- // 'revealing' it. For example, code like this:
1359
- //
1360
- // type Foo = impl Debug;
1361
- // fn foo1() -> Foo { ... }
1362
- // fn foo2() -> Foo { foo1() }
1363
- //
1364
- // In `foo2`, we're not revealing the type of `Foo` - we're
1365
- // just treating it as the opaque type.
1366
- //
1367
- // When this occurs, we do *not* want to try to equate
1368
- // the concrete type with the underlying defining type
1369
- // of the opaque type - this will always fail, since
1370
- // the defining type of an opaque type is always
1371
- // some other type (e.g. not itself)
1372
- // Essentially, none of the normal obligations apply here -
1373
- // we're just passing around some unknown opaque type,
1374
- // without actually looking at the underlying type it
1375
- // gets 'revealed' into
1376
- debug ! (
1377
- "eq_opaque_type_and_type: non-defining use of {:?}" ,
1378
- opaque_type_key. def_id,
1379
- ) ;
1380
- }
1355
+ opaque_type_values. insert ( opaque_type_key, opaque_decl. concrete_ty ) ;
1381
1356
}
1382
1357
1383
1358
debug ! ( "eq_opaque_type_and_type: equated" ) ;
0 commit comments