@@ -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_concrete_opaque_types ( & opaque_types, true ) ;
37- self . apply_computed_concrete_opaque_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_concrete_opaque_types ( & opaque_types, false ) ;
62- self . apply_computed_concrete_opaque_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,66 @@ 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 = self
154+ . typeck_results
155+ . borrow_mut ( )
156+ . concrete_opaque_types
157+ . insert ( def_id, hidden_type) ;
158+
159+ // We do want to insert opaque types the first pass, because
160+ // we want to equate them. So, the second pass (where we
161+ // report errors) may have a hidden type inserted.
162+ if first_pass {
163+ assert ! ( prev. is_none( ) ) ;
164+ }
165+ }
166+ UsageKind :: HasError ( guar) => {
167+ self . typeck_results
168+ . borrow_mut ( )
169+ . concrete_opaque_types
170+ . insert ( def_id, OpaqueHiddenType :: new_error ( self . tcx , guar) ) ;
171+ }
172+ _ => { }
173+ }
174+
131175 // If this the first pass (`try_handle_opaque_type_uses_next`),
132176 // then do not report any errors.
133177 if first_pass {
134178 continue ;
135179 }
136180
137181 let guar = match usage_kind {
182+ UsageKind :: HasDefiningUse ( _) | UsageKind :: HasError ( _) => continue ,
138183 UsageKind :: None => {
139184 if let Some ( guar) = self . tainted_by_errors ( ) {
140185 guar
@@ -171,7 +216,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
171216 . emit ( )
172217 }
173218 }
174- UsageKind :: HasDefiningUse => continue ,
175219 } ;
176220
177221 self . typeck_results
@@ -182,11 +226,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
182226 }
183227 }
184228
229+ #[ tracing:: instrument( skip( self ) , ret) ]
185230 fn consider_opaque_type_use (
186231 & mut self ,
187232 opaque_type_key : OpaqueTypeKey < ' tcx > ,
188233 hidden_type : OpaqueHiddenType < ' tcx > ,
189- first_pass : bool ,
190234 ) -> UsageKind < ' tcx > {
191235 if let Err ( err) = opaque_type_has_defining_use_args (
192236 & self ,
@@ -196,11 +240,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
196240 ) {
197241 match err {
198242 NonDefiningUseReason :: Tainted ( guar) => {
199- self . typeck_results . borrow_mut ( ) . concrete_opaque_types . insert (
200- opaque_type_key. def_id ,
201- OpaqueHiddenType :: new_error ( self . tcx , guar) ,
202- ) ;
203- return UsageKind :: HasDefiningUse ;
243+ return UsageKind :: HasError ( guar) ;
204244 }
205245 _ => return UsageKind :: NonDefiningUse ( opaque_type_key, hidden_type) ,
206246 } ;
@@ -228,37 +268,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
228268 self . tcx ,
229269 DefiningScopeKind :: HirTypeck ,
230270 ) ;
231-
232- let prev = self
233- . typeck_results
234- . borrow_mut ( )
235- . concrete_opaque_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_computed_concrete_opaque_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) =
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- }
261- }
271+ UsageKind :: HasDefiningUse ( hidden_type)
262272 }
263273
264274 /// We may in theory add further uses of an opaque after cloning the opaque
0 commit comments