@@ -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,54 @@ 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+ * revealed_ty = infcx. resolve_vars_if_possible ( * revealed_ty) ;
186+ if revealed_ty. has_infer_types_or_consts ( ) {
187+ infcx. tcx . sess . delay_span_bug (
188+ body. span ,
189+ & format ! ( "could not resolve {:#?}" , revealed_ty. kind( ) ) ,
190+ ) ;
191+ * revealed_ty = infcx. tcx . ty_error ( ) ;
192+ }
193+ }
194+
195+ opaque_type_values. retain ( |( opaque_type_key, resolved_ty) | {
196+ let concrete_is_opaque = if let ty:: Opaque ( def_id, _) = resolved_ty. kind ( ) {
197+ * def_id == opaque_type_key. def_id
198+ } else {
199+ false
200+ } ;
201+
202+ if concrete_is_opaque {
203+ // We're using an opaque `impl Trait` type without
204+ // 'revealing' it. For example, code like this:
205+ //
206+ // type Foo = impl Debug;
207+ // fn foo1() -> Foo { ... }
208+ // fn foo2() -> Foo { foo1() }
209+ //
210+ // In `foo2`, we're not revealing the type of `Foo` - we're
211+ // just treating it as the opaque type.
212+ //
213+ // When this occurs, we do *not* want to try to equate
214+ // the concrete type with the underlying defining type
215+ // of the opaque type - this will always fail, since
216+ // the defining type of an opaque type is always
217+ // some other type (e.g. not itself)
218+ // Essentially, none of the normal obligations apply here -
219+ // we're just passing around some unknown opaque type,
220+ // without actually looking at the underlying type it
221+ // gets 'revealed' into
222+ debug ! (
223+ "eq_opaque_type_and_type: non-defining use of {:?}" ,
224+ opaque_type_key. def_id,
225+ ) ;
226+ }
227+ !concrete_is_opaque
228+ } ) ;
229+ opaque_type_values
184230 } ,
185231 ) ;
186232
@@ -1239,14 +1285,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12391285 return Ok ( ( ) ) ;
12401286 }
12411287
1242- let infcx = self . infcx ;
1243- let tcx = infcx. tcx ;
12441288 let param_env = self . param_env ;
12451289 let body = self . body ;
12461290 let mir_def_id = body. source . def_id ( ) . expect_local ( ) ;
12471291
1248- // the "concrete opaque types" maps
1249- let concrete_opaque_types = & tcx. typeck ( mir_def_id) . concrete_opaque_types ;
12501292 let mut opaque_type_values = VecMap :: new ( ) ;
12511293
12521294 debug ! ( "eq_opaque_type_and_type: mir_def_id={:?}" , mir_def_id) ;
@@ -1296,88 +1338,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12961338 . eq ( output_ty, revealed_ty) ?,
12971339 ) ;
12981340
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.
13021341 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- }
1342+ opaque_type_values. insert ( opaque_type_key, opaque_decl. concrete_ty ) ;
13811343 }
13821344
13831345 debug ! ( "eq_opaque_type_and_type: equated" ) ;
@@ -1405,7 +1367,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
14051367 locations,
14061368 ConstraintCategory :: OpaqueType ,
14071369 CustomTypeOp :: new (
1408- |_cx | {
1370+ |infcx | {
14091371 infcx. constrain_opaque_type (
14101372 opaque_type_key,
14111373 & opaque_decl,
0 commit comments