@@ -1206,6 +1206,36 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12061206 Ok ( ( ) )
12071207 }
12081208
1209+ /// Equates a type `anon_ty` that may contain opaque types whose
1210+ /// values are to be inferred by the MIR with def-id `anon_owner_def_id`.
1211+ ///
1212+ /// The type `revealed_ty` contains the same type as `anon_ty`, but with the
1213+ /// hidden types for impl traits revealed.
1214+ ///
1215+ /// # Example
1216+ ///
1217+ /// Consider a piece of code like
1218+ ///
1219+ /// ```rust
1220+ /// type Foo<U> = impl Debug;
1221+ ///
1222+ /// fn foo<T: Debug>(t: T) -> Box<Foo<T>> {
1223+ /// Box::new((t, 22_u32))
1224+ /// }
1225+ /// ```
1226+ ///
1227+ /// Here, the function signature would be something like
1228+ /// `fn(T) -> Box<impl Debug>`. The MIR return slot would have
1229+ /// the type with the opaque type revealed, so `Box<(T, u32)>`.
1230+ ///
1231+ /// In terms of our function parameters:
1232+ ///
1233+ /// * `anon_ty` would be `Box<Foo<T>>` where `Foo<T>` is an opaque type
1234+ /// scoped to this function (note that it is parameterized by the
1235+ /// generics of `foo`). Note that `anon_ty` is not just the opaque type,
1236+ /// but the entire return type (which may contain opaque types within it).
1237+ /// * `revealed_ty` would be `Box<(T, u32)>`
1238+ /// * `anon_owner_def_id` would be the def-id of `foo`
12091239 fn eq_opaque_type_and_type (
12101240 & mut self ,
12111241 revealed_ty : Ty < ' tcx > ,
@@ -1240,6 +1270,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12401270 let tcx = infcx. tcx ;
12411271 let param_env = self . param_env ;
12421272 let body = self . body ;
1273+
1274+ // the "concrete opaque types" maps
12431275 let concrete_opaque_types = & tcx. typeck ( anon_owner_def_id) . concrete_opaque_types ;
12441276 let mut opaque_type_values = VecMap :: new ( ) ;
12451277
@@ -1252,6 +1284,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12521284 let mut obligations = ObligationAccumulator :: default ( ) ;
12531285
12541286 let dummy_body_id = hir:: CRATE_HIR_ID ;
1287+
1288+ // Replace the opaque types defined by this function with
1289+ // inference variables, creating a map. In our example above,
1290+ // this would transform the type `Box<Foo<T>>` (where `Foo` is an opaque type)
1291+ // to `Box<?T>`, returning an `opaque_type_map` mapping `{Foo<T> -> ?T}`.
1292+ // (Note that the key of the map is both the def-id of `Foo` along with
1293+ // any generic parameters.)
12551294 let ( output_ty, opaque_type_map) =
12561295 obligations. add ( infcx. instantiate_opaque_types (
12571296 anon_owner_def_id,
@@ -1267,6 +1306,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12671306 revealed_ty={:?}",
12681307 output_ty, opaque_type_map, revealed_ty
12691308 ) ;
1309+
12701310 // Make sure that the inferred types are well-formed. I'm
12711311 // not entirely sure this is needed (the HIR type check
12721312 // didn't do this) but it seems sensible to prevent opaque
@@ -1282,6 +1322,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12821322 . eq ( output_ty, revealed_ty) ?,
12831323 ) ;
12841324
1325+ // For each opaque type `Foo<T>` inferred by this value, we want to equate
1326+ // the inference variable `?T` with the revealed type that was computed
1327+ // earlier by type check.
12851328 for & ( opaque_type_key, opaque_decl) in & opaque_type_map {
12861329 let resolved_ty = infcx. resolve_vars_if_possible ( opaque_decl. concrete_ty ) ;
12871330 let concrete_is_opaque = if let ty:: Opaque ( def_id, _) = resolved_ty. kind ( ) {
@@ -1290,6 +1333,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12901333 false
12911334 } ;
12921335
1336+ // The revealed type computed by the earlier phase of type check.
1337+ // In our example, this would be `(U, u32)`. Note that this references
1338+ // the type parameter `U` from the definition of `Foo`.
12931339 let concrete_ty = match concrete_opaque_types
12941340 . get_by ( |( key, _) | key. def_id == opaque_type_key. def_id )
12951341 {
@@ -1308,7 +1354,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13081354 Some ( concrete_ty) => concrete_ty,
13091355 } ;
13101356 debug ! ( "concrete_ty = {:?}" , concrete_ty) ;
1357+
1358+ // Apply the substitution, in this case `[U -> T]`, so that the
1359+ // concrete type becomes `Foo<(T, u32)>`
13111360 let subst_opaque_defn_ty = concrete_ty. subst ( tcx, opaque_type_key. substs ) ;
1361+
1362+ // "Renumber" this, meaning that we replace all the regions
1363+ // with fresh inference variables. Not relevant to our example.
13121364 let renumbered_opaque_defn_ty =
13131365 renumber:: renumber_regions ( infcx, subst_opaque_defn_ty) ;
13141366
@@ -1318,8 +1370,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13181370 ) ;
13191371
13201372 if !concrete_is_opaque {
1321- // Equate concrete_ty (an inference variable) with
1322- // the renumbered type from typeck.
1373+ // Equate the instantiated opaque type `opaque_decl.concrete_ty` (`?T`,
1374+ // in our example) with the renumbered version that we took from
1375+ // the type check results (`Foo<(T, u32)>`).
13231376 obligations. add (
13241377 infcx
13251378 . at ( & ObligationCause :: dummy ( ) , param_env)
0 commit comments