@@ -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