@@ -14,6 +14,29 @@ use tracing::{debug, instrument};
14
14
use crate :: FnCtxt ;
15
15
16
16
impl < ' 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
+
17
40
/// This takes all the opaque type uses during HIR typeck. It first computes
18
41
/// the concrete hidden type by iterating over all defining uses.
19
42
///
@@ -35,7 +58,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
35
58
}
36
59
debug ! ( ?opaque_types) ;
37
60
38
- self . compute_concrete_opaque_types ( & opaque_types) ;
61
+ self . compute_concrete_opaque_types ( & opaque_types, false ) ;
39
62
self . apply_computed_concrete_opaque_types ( & opaque_types) ;
40
63
}
41
64
}
@@ -74,6 +97,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
74
97
fn compute_concrete_opaque_types (
75
98
& mut self ,
76
99
opaque_types : & [ ( OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > ) ] ,
100
+ first_pass : bool ,
77
101
) {
78
102
let tcx = self . tcx ;
79
103
let TypingMode :: Analysis { defining_opaque_types_and_generators } = self . typing_mode ( )
@@ -94,12 +118,22 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
94
118
continue ;
95
119
}
96
120
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
+ ) ) ;
98
126
if let UsageKind :: HasDefiningUse = usage_kind {
99
127
break ;
100
128
}
101
129
}
102
130
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
+
103
137
let guar = match usage_kind {
104
138
UsageKind :: None => {
105
139
if let Some ( guar) = self . tainted_by_errors ( ) {
@@ -152,6 +186,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
152
186
& mut self ,
153
187
opaque_type_key : OpaqueTypeKey < ' tcx > ,
154
188
hidden_type : OpaqueHiddenType < ' tcx > ,
189
+ first_pass : bool ,
155
190
) -> UsageKind < ' tcx > {
156
191
if let Err ( err) = opaque_type_has_defining_use_args (
157
192
& self ,
@@ -199,7 +234,13 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
199
234
. borrow_mut ( )
200
235
. concrete_opaque_types
201
236
. 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
+ }
203
244
UsageKind :: HasDefiningUse
204
245
}
205
246
@@ -209,11 +250,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
209
250
) {
210
251
let tcx = self . tcx ;
211
252
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
+ }
217
261
}
218
262
}
219
263
0 commit comments