@@ -14,6 +14,29 @@ use tracing::{debug, instrument};
1414use  crate :: FnCtxt ; 
1515
1616impl < ' tcx >  FnCtxt < ' _ ,  ' tcx >  { 
17+     /// This takes all the opaque type uses during HIR typeck. It first computes 
18+      /// the concrete hidden type by iterating over all defining uses. 
19+      /// 
20+      /// A use during HIR typeck is defining if all non-lifetime arguments are 
21+      /// unique generic parameters and the hidden type does not reference any 
22+      /// inference variables. 
23+      /// 
24+      /// It then uses these defining uses to guide inference for all other uses. 
25+      /// 
26+      /// Unlike `handle_opaque_type_uses_next`, this does not report errors. 
27+      pub ( super )  fn  try_handle_opaque_type_uses_next ( & mut  self )  { 
28+         // We clone the opaques instead of stealing them here as they are still used for 
29+         // normalization in the next generation trait solver. 
30+         let  mut  opaque_types:  Vec < _ >  = self . infcx . clone_opaque_types ( ) ; 
31+         for  entry in  & mut  opaque_types { 
32+             * entry = self . resolve_vars_if_possible ( * entry) ; 
33+         } 
34+         debug ! ( ?opaque_types) ; 
35+ 
36+         self . compute_concrete_opaque_types ( & opaque_types,  true ) ; 
37+         self . apply_computed_concrete_opaque_types ( & opaque_types) ; 
38+     } 
39+ 
1740    /// This takes all the opaque type uses during HIR typeck. It first computes 
1841     /// the concrete hidden type by iterating over all defining uses. 
1942     /// 
@@ -35,7 +58,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
3558        } 
3659        debug ! ( ?opaque_types) ; 
3760
38-         self . compute_concrete_opaque_types ( & opaque_types) ; 
61+         self . compute_concrete_opaque_types ( & opaque_types,   false ) ; 
3962        self . apply_computed_concrete_opaque_types ( & opaque_types) ; 
4063    } 
4164} 
@@ -74,6 +97,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
7497    fn  compute_concrete_opaque_types ( 
7598        & mut  self , 
7699        opaque_types :  & [ ( OpaqueTypeKey < ' tcx > ,  OpaqueHiddenType < ' tcx > ) ] , 
100+         first_pass :  bool , 
77101    )  { 
78102        let  tcx = self . tcx ; 
79103        let  TypingMode :: Analysis  {  defining_opaque_types_and_generators }  = self . typing_mode ( ) 
@@ -94,12 +118,22 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
94118                    continue ; 
95119                } 
96120
97-                 usage_kind. merge ( self . consider_opaque_type_use ( opaque_type_key,  hidden_type) ) ; 
121+                 usage_kind. merge ( self . consider_opaque_type_use ( 
122+                     opaque_type_key, 
123+                     hidden_type, 
124+                     first_pass, 
125+                 ) ) ; 
98126                if  let  UsageKind :: HasDefiningUse  = usage_kind { 
99127                    break ; 
100128                } 
101129            } 
102130
131+             // If this the first pass (`try_handle_opaque_type_uses_next`), 
132+             // then do not report any errors. 
133+             if  first_pass { 
134+                 continue ; 
135+             } 
136+ 
103137            let  guar = match  usage_kind { 
104138                UsageKind :: None  => { 
105139                    if  let  Some ( guar)  = self . tainted_by_errors ( )  { 
@@ -152,6 +186,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
152186        & mut  self , 
153187        opaque_type_key :  OpaqueTypeKey < ' tcx > , 
154188        hidden_type :  OpaqueHiddenType < ' tcx > , 
189+         first_pass :  bool , 
155190    )  -> UsageKind < ' tcx >  { 
156191        if  let  Err ( err)  = opaque_type_has_defining_use_args ( 
157192            & self , 
@@ -199,7 +234,13 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
199234            . borrow_mut ( ) 
200235            . concrete_opaque_types 
201236            . insert ( opaque_type_key. def_id ,  hidden_type) ; 
202-         assert ! ( prev. is_none( ) ) ; 
237+ 
238+         // We do want to insert opaque types the first pass, because we want to 
239+         // equate them. So, the second pass (where we report errors) will have 
240+         // a hidden type inserted. 
241+         if  first_pass { 
242+             assert ! ( prev. is_none( ) ) ; 
243+         } 
203244        UsageKind :: HasDefiningUse 
204245    } 
205246
@@ -209,11 +250,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
209250    )  { 
210251        let  tcx = self . tcx ; 
211252        for  & ( key,  hidden_type)  in  opaque_types { 
212-             let  expected =
213-                 * self . typeck_results . borrow_mut ( ) . concrete_opaque_types . get ( & key. def_id ) . unwrap ( ) ; 
214- 
215-             let  expected = EarlyBinder :: bind ( expected. ty ) . instantiate ( tcx,  key. args ) ; 
216-             self . demand_eqtype ( hidden_type. span ,  expected,  hidden_type. ty ) ; 
253+             // On the first pass to this function, some opaque types may not 
254+             // have a hidden type assigned. 
255+             if  let  Some ( expected)  =
256+                 self . typeck_results . borrow_mut ( ) . concrete_opaque_types . get ( & key. def_id ) 
257+             { 
258+                 let  expected = EarlyBinder :: bind ( expected. ty ) . instantiate ( tcx,  key. args ) ; 
259+                 self . demand_eqtype ( hidden_type. span ,  expected,  hidden_type. ty ) ; 
260+             } 
217261        } 
218262    } 
219263
0 commit comments