@@ -4,6 +4,7 @@ use rustc_middle::ty::{
44 self , DefiningScopeKind , EarlyBinder , OpaqueHiddenType , OpaqueTypeKey , TypeVisitableExt ,
55 TypingMode ,
66} ;
7+ use rustc_span:: ErrorGuaranteed ;
78use rustc_trait_selection:: error_reporting:: infer:: need_type_info:: TypeAnnotationNeeded ;
89use rustc_trait_selection:: opaque_types:: {
910 NonDefiningUseReason , opaque_type_has_defining_use_args, report_item_does_not_constrain_error,
@@ -24,6 +25,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
2425 /// It then uses these defining uses to guide inference for all other uses.
2526 ///
2627 /// Unlike `handle_opaque_type_uses_next`, this does not report errors.
28+ #[ instrument( level = "debug" , skip( self ) ) ]
2729 pub ( super ) fn try_handle_opaque_type_uses_next ( & mut self ) {
2830 // We clone the opaques instead of stealing them here as they are still used for
2931 // normalization in the next generation trait solver.
@@ -34,7 +36,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
3436 debug ! ( ?opaque_types) ;
3537
3638 self . compute_definition_site_hidden_types ( & opaque_types, true ) ;
37- self . apply_definition_site_hidden_types ( & opaque_types) ;
3839 }
3940
4041 /// This takes all the opaque type uses during HIR typeck. It first computes
@@ -59,22 +60,29 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
5960 debug ! ( ?opaque_types) ;
6061
6162 self . compute_definition_site_hidden_types ( & opaque_types, false ) ;
62- self . apply_definition_site_hidden_types ( & opaque_types) ;
6363 }
6464}
6565
66+ #[ derive( Copy , Clone , Debug ) ]
6667enum UsageKind < ' tcx > {
6768 None ,
6869 NonDefiningUse ( OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > ) ,
6970 UnconstrainedHiddenType ( OpaqueHiddenType < ' tcx > ) ,
70- HasDefiningUse ,
71+ HasDefiningUse ( OpaqueHiddenType < ' tcx > ) ,
72+ // `type_of_opaque_hir_typeck` reported an error
73+ HasError ( ErrorGuaranteed ) ,
7174}
7275
7376impl < ' tcx > UsageKind < ' tcx > {
7477 fn merge ( & mut self , other : UsageKind < ' tcx > ) {
7578 match ( & * self , & other) {
76- ( UsageKind :: HasDefiningUse , _) | ( _, UsageKind :: None ) => unreachable ! ( ) ,
79+ ( UsageKind :: HasDefiningUse ( _ ) , _) | ( _, UsageKind :: None ) => unreachable ! ( ) ,
7780 ( UsageKind :: None , _) => * self = other,
81+ // If `type_of_opaque_hir_typeck` reported an error, then the hidden
82+ // type is an error, but we also want to still report errors for
83+ // remaining hidden types (really just normalization errors).
84+ ( UsageKind :: HasError ( _) , _) => { }
85+ ( _, UsageKind :: HasError ( _) ) => * self = other,
7886 // When mergining non-defining uses, prefer earlier ones. This means
7987 // the error happens as early as possible.
8088 (
@@ -87,7 +95,7 @@ impl<'tcx> UsageKind<'tcx> {
8795 // intended to be defining.
8896 (
8997 UsageKind :: NonDefiningUse ( ..) | UsageKind :: UnconstrainedHiddenType ( ..) ,
90- UsageKind :: UnconstrainedHiddenType ( ..) | UsageKind :: HasDefiningUse ,
98+ UsageKind :: UnconstrainedHiddenType ( ..) | UsageKind :: HasDefiningUse ( _ ) ,
9199 ) => * self = other,
92100 }
93101 }
@@ -112,29 +120,63 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
112120 _ => unreachable ! ( "not opaque or generator: {def_id:?}" ) ,
113121 }
114122
123+ // We do actually need to check this the second pass (we can't just
124+ // store this), because we can go from `UnconstrainedHiddenType` to
125+ // `HasDefiningUse` (because of fallback)
115126 let mut usage_kind = UsageKind :: None ;
116127 for & ( opaque_type_key, hidden_type) in opaque_types {
117128 if opaque_type_key. def_id != def_id {
118129 continue ;
119130 }
120131
121- usage_kind. merge ( self . consider_opaque_type_use (
122- opaque_type_key,
123- hidden_type,
124- first_pass,
125- ) ) ;
126- if let UsageKind :: HasDefiningUse = usage_kind {
132+ usage_kind. merge ( self . consider_opaque_type_use ( opaque_type_key, hidden_type) ) ;
133+
134+ if let UsageKind :: HasDefiningUse ( ..) = usage_kind {
127135 break ;
128136 }
129137 }
130138
139+ if let UsageKind :: HasDefiningUse ( first_use) = usage_kind {
140+ for & ( opaque_type_key, hidden_type) in opaque_types {
141+ if opaque_type_key. def_id != def_id {
142+ continue ;
143+ }
144+
145+ let expected =
146+ EarlyBinder :: bind ( first_use. ty ) . instantiate ( tcx, opaque_type_key. args ) ;
147+ self . demand_eqtype ( hidden_type. span , expected, hidden_type. ty ) ;
148+ }
149+ }
150+
151+ match usage_kind {
152+ UsageKind :: HasDefiningUse ( hidden_type) => {
153+ let prev =
154+ self . typeck_results . borrow_mut ( ) . hidden_types . insert ( def_id, hidden_type) ;
155+
156+ // We do want to insert opaque types the first pass, because
157+ // we want to equate them. So, the second pass (where we
158+ // report errors) may have a hidden type inserted.
159+ if first_pass {
160+ assert ! ( prev. is_none( ) ) ;
161+ }
162+ }
163+ UsageKind :: HasError ( guar) => {
164+ self . typeck_results
165+ . borrow_mut ( )
166+ . hidden_types
167+ . insert ( def_id, OpaqueHiddenType :: new_error ( self . tcx , guar) ) ;
168+ }
169+ _ => { }
170+ }
171+
131172 // If this the first pass (`try_handle_opaque_type_uses_next`),
132173 // then do not report any errors.
133174 if first_pass {
134175 continue ;
135176 }
136177
137178 let guar = match usage_kind {
179+ UsageKind :: HasDefiningUse ( _) | UsageKind :: HasError ( _) => continue ,
138180 UsageKind :: None => {
139181 if let Some ( guar) = self . tainted_by_errors ( ) {
140182 guar
@@ -171,7 +213,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
171213 . emit ( )
172214 }
173215 }
174- UsageKind :: HasDefiningUse => continue ,
175216 } ;
176217
177218 self . typeck_results
@@ -182,11 +223,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
182223 }
183224 }
184225
226+ #[ tracing:: instrument( skip( self ) , ret) ]
185227 fn consider_opaque_type_use (
186228 & mut self ,
187229 opaque_type_key : OpaqueTypeKey < ' tcx > ,
188230 hidden_type : OpaqueHiddenType < ' tcx > ,
189- first_pass : bool ,
190231 ) -> UsageKind < ' tcx > {
191232 if let Err ( err) = opaque_type_has_defining_use_args (
192233 & self ,
@@ -196,11 +237,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
196237 ) {
197238 match err {
198239 NonDefiningUseReason :: Tainted ( guar) => {
199- self . typeck_results . borrow_mut ( ) . hidden_types . insert (
200- opaque_type_key. def_id ,
201- OpaqueHiddenType :: new_error ( self . tcx , guar) ,
202- ) ;
203- return UsageKind :: HasDefiningUse ;
240+ return UsageKind :: HasError ( guar) ;
204241 }
205242 _ => return UsageKind :: NonDefiningUse ( opaque_type_key, hidden_type) ,
206243 } ;
@@ -228,35 +265,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
228265 self . tcx ,
229266 DefiningScopeKind :: HirTypeck ,
230267 ) ;
231-
232- let prev = self
233- . typeck_results
234- . borrow_mut ( )
235- . hidden_types
236- . insert ( opaque_type_key. def_id , hidden_type) ;
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- }
244- UsageKind :: HasDefiningUse
245- }
246-
247- fn apply_definition_site_hidden_types (
248- & mut self ,
249- opaque_types : & [ ( OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > ) ] ,
250- ) {
251- let tcx = self . tcx ;
252- for & ( key, hidden_type) in opaque_types {
253- // On the first pass to this function, some opaque types may not
254- // have a hidden type assigned.
255- if let Some ( expected) = self . typeck_results . borrow_mut ( ) . hidden_types . get ( & key. def_id ) {
256- let expected = EarlyBinder :: bind ( expected. ty ) . instantiate ( tcx, key. args ) ;
257- self . demand_eqtype ( hidden_type. span , expected, hidden_type. ty ) ;
258- }
259- }
268+ UsageKind :: HasDefiningUse ( hidden_type)
260269 }
261270
262271 /// We may in theory add further uses of an opaque after cloning the opaque
0 commit comments