@@ -26,7 +26,7 @@ use rustc_middle::mir::*;
2626use rustc_middle:: ty:: adjustment:: PointerCast ;
2727use rustc_middle:: ty:: cast:: CastTy ;
2828use rustc_middle:: ty:: fold:: TypeFoldable ;
29- use rustc_middle:: ty:: subst:: { GenericArgKind , Subst , SubstsRef , UserSubsts } ;
29+ use rustc_middle:: ty:: subst:: { GenericArgKind , SubstsRef , UserSubsts } ;
3030use rustc_middle:: ty:: {
3131 self , CanonicalUserTypeAnnotation , CanonicalUserTypeAnnotations , OpaqueTypeKey , RegionVid ,
3232 ToPredicate , Ty , TyCtxt , UserType , UserTypeAnnotationIndex , WithConstness ,
@@ -60,7 +60,6 @@ use crate::borrow_check::{
6060 LivenessValues , PlaceholderIndex , PlaceholderIndices , RegionValueElements ,
6161 } ,
6262 region_infer:: { ClosureRegionRequirementsExt , TypeTest } ,
63- renumber,
6463 type_check:: free_region_relations:: { CreateResult , UniversalRegionRelations } ,
6564 universal_regions:: { DefiningTy , UniversalRegions } ,
6665 Upvar ,
@@ -180,7 +179,66 @@ pub(crate) fn type_check<'mir, 'tcx>(
180179 liveness:: generate ( & mut cx, body, elements, flow_inits, move_data, location_table) ;
181180
182181 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
184242 } ,
185243 ) ;
186244
@@ -1240,13 +1298,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12401298 }
12411299
12421300 let infcx = self . infcx ;
1243- let tcx = infcx. tcx ;
12441301 let param_env = self . param_env ;
12451302 let body = self . body ;
12461303 let mir_def_id = body. source . def_id ( ) . expect_local ( ) ;
12471304
1248- // the "concrete opaque types" maps
1249- let concrete_opaque_types = & tcx. typeck ( mir_def_id) . concrete_opaque_types ;
12501305 let mut opaque_type_values = VecMap :: new ( ) ;
12511306
12521307 debug ! ( "eq_opaque_type_and_type: mir_def_id={:?}" , mir_def_id) ;
@@ -1296,88 +1351,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12961351 . eq ( output_ty, revealed_ty) ?,
12971352 ) ;
12981353
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.
13021354 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 ) ;
13811356 }
13821357
13831358 debug ! ( "eq_opaque_type_and_type: equated" ) ;
0 commit comments