@@ -22,35 +22,50 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
2222 /// inference variables.
2323 ///
2424 /// 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+ #[ instrument( level = "debug" , skip( self ) ) ]
28+ pub ( super ) fn try_handle_opaque_type_uses_next ( & mut self ) {
29+ // We clone the opaques instead of stealing them here as we still need
30+ // to use them after fallback.
31+ let opaque_types: Vec < _ > = self . infcx . clone_opaque_types ( ) ;
32+
33+ self . compute_definition_site_hidden_types ( opaque_types, false ) ;
34+ }
35+
36+ /// This takes all the opaque type uses during HIR typeck. It first computes
37+ /// the concrete hidden type by iterating over all defining uses.
38+ ///
39+ /// A use during HIR typeck is defining if all non-lifetime arguments are
40+ /// unique generic parameters and the hidden type does not reference any
41+ /// inference variables.
42+ ///
43+ /// It then uses these defining uses to guide inference for all other uses.
2544 #[ instrument( level = "debug" , skip( self ) ) ]
2645 pub ( super ) fn handle_opaque_type_uses_next ( & mut self ) {
2746 // We clone the opaques instead of stealing them here as they are still used for
2847 // normalization in the next generation trait solver.
29- let mut opaque_types: Vec < _ > = self . infcx . clone_opaque_types ( ) ;
48+ let opaque_types: Vec < _ > = self . infcx . clone_opaque_types ( ) ;
3049 let num_entries = self . inner . borrow_mut ( ) . opaque_types ( ) . num_entries ( ) ;
3150 let prev = self . checked_opaque_types_storage_entries . replace ( Some ( num_entries) ) ;
3251 debug_assert_eq ! ( prev, None ) ;
33- for entry in & mut opaque_types {
34- * entry = self . resolve_vars_if_possible ( * entry) ;
35- }
36- debug ! ( ?opaque_types) ;
3752
38- self . compute_definition_site_hidden_types ( & opaque_types) ;
39- self . apply_definition_site_hidden_types ( & opaque_types) ;
53+ self . compute_definition_site_hidden_types ( opaque_types, true ) ;
4054 }
4155}
4256
57+ #[ derive( Copy , Clone , Debug ) ]
4358enum UsageKind < ' tcx > {
4459 None ,
4560 NonDefiningUse ( OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > ) ,
4661 UnconstrainedHiddenType ( OpaqueHiddenType < ' tcx > ) ,
47- HasDefiningUse ,
62+ HasDefiningUse ( OpaqueHiddenType < ' tcx > ) ,
4863}
4964
5065impl < ' tcx > UsageKind < ' tcx > {
5166 fn merge ( & mut self , other : UsageKind < ' tcx > ) {
5267 match ( & * self , & other) {
53- ( UsageKind :: HasDefiningUse , _) | ( _, UsageKind :: None ) => unreachable ! ( ) ,
68+ ( UsageKind :: HasDefiningUse ( _ ) , _) | ( _, UsageKind :: None ) => unreachable ! ( ) ,
5469 ( UsageKind :: None , _) => * self = other,
5570 // When mergining non-defining uses, prefer earlier ones. This means
5671 // the error happens as early as possible.
@@ -64,7 +79,7 @@ impl<'tcx> UsageKind<'tcx> {
6479 // intended to be defining.
6580 (
6681 UsageKind :: NonDefiningUse ( ..) | UsageKind :: UnconstrainedHiddenType ( ..) ,
67- UsageKind :: UnconstrainedHiddenType ( ..) | UsageKind :: HasDefiningUse ,
82+ UsageKind :: UnconstrainedHiddenType ( ..) | UsageKind :: HasDefiningUse ( _ ) ,
6883 ) => * self = other,
6984 }
7085 }
@@ -73,8 +88,14 @@ impl<'tcx> UsageKind<'tcx> {
7388impl < ' tcx > FnCtxt < ' _ , ' tcx > {
7489 fn compute_definition_site_hidden_types (
7590 & mut self ,
76- opaque_types : & [ ( OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > ) ] ,
91+ mut opaque_types : Vec < ( OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > ) > ,
92+ error_on_missing_defining_use : bool ,
7793 ) {
94+ for entry in opaque_types. iter_mut ( ) {
95+ * entry = self . resolve_vars_if_possible ( * entry) ;
96+ }
97+ debug ! ( ?opaque_types) ;
98+
7899 let tcx = self . tcx ;
79100 let TypingMode :: Analysis { defining_opaque_types_and_generators } = self . typing_mode ( )
80101 else {
@@ -88,19 +109,47 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
88109 _ => unreachable ! ( "not opaque or generator: {def_id:?}" ) ,
89110 }
90111
112+ // We do actually need to check this the second pass (we can't just
113+ // store this), because we can go from `UnconstrainedHiddenType` to
114+ // `HasDefiningUse` (because of fallback)
91115 let mut usage_kind = UsageKind :: None ;
92- for & ( opaque_type_key, hidden_type) in opaque_types {
116+ for & ( opaque_type_key, hidden_type) in & opaque_types {
93117 if opaque_type_key. def_id != def_id {
94118 continue ;
95119 }
96120
97121 usage_kind. merge ( self . consider_opaque_type_use ( opaque_type_key, hidden_type) ) ;
98- if let UsageKind :: HasDefiningUse = usage_kind {
122+
123+ if let UsageKind :: HasDefiningUse ( ..) = usage_kind {
99124 break ;
100125 }
101126 }
102127
128+ if let UsageKind :: HasDefiningUse ( ty) = usage_kind {
129+ for & ( opaque_type_key, hidden_type) in & opaque_types {
130+ if opaque_type_key. def_id != def_id {
131+ continue ;
132+ }
133+
134+ let expected = EarlyBinder :: bind ( ty. ty ) . instantiate ( tcx, opaque_type_key. args ) ;
135+ self . demand_eqtype ( hidden_type. span , expected, hidden_type. ty ) ;
136+ }
137+
138+ // Being explicit here: it may be possible that we in a
139+ // previous call to this function we did an insert, but this
140+ // should be just fine, since they all get equated anyways and
141+ // we shouldn't ever go from `HasDefiningUse` to anyway else.
142+ let _ = self . typeck_results . borrow_mut ( ) . hidden_types . insert ( def_id, ty) ;
143+ }
144+
145+ // If we're in `fn try_handle_opaque_type_uses_next` then do not
146+ // report any errors.
147+ if !error_on_missing_defining_use {
148+ continue ;
149+ }
150+
103151 let guar = match usage_kind {
152+ UsageKind :: HasDefiningUse ( _) => continue ,
104153 UsageKind :: None => {
105154 if let Some ( guar) = self . tainted_by_errors ( ) {
106155 guar
@@ -137,7 +186,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
137186 . emit ( )
138187 }
139188 }
140- UsageKind :: HasDefiningUse => continue ,
141189 } ;
142190
143191 self . typeck_results
@@ -148,8 +196,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
148196 }
149197 }
150198
199+ #[ tracing:: instrument( skip( self ) , ret) ]
151200 fn consider_opaque_type_use (
152- & mut self ,
201+ & self ,
153202 opaque_type_key : OpaqueTypeKey < ' tcx > ,
154203 hidden_type : OpaqueHiddenType < ' tcx > ,
155204 ) -> UsageKind < ' tcx > {
@@ -161,11 +210,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
161210 ) {
162211 match err {
163212 NonDefiningUseReason :: Tainted ( guar) => {
164- self . typeck_results . borrow_mut ( ) . hidden_types . insert (
165- opaque_type_key. def_id ,
166- OpaqueHiddenType :: new_error ( self . tcx , guar) ,
167- ) ;
168- return UsageKind :: HasDefiningUse ;
213+ return UsageKind :: HasDefiningUse ( OpaqueHiddenType :: new_error ( self . tcx , guar) ) ;
169214 }
170215 _ => return UsageKind :: NonDefiningUse ( opaque_type_key, hidden_type) ,
171216 } ;
@@ -193,27 +238,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
193238 self . tcx ,
194239 DefiningScopeKind :: HirTypeck ,
195240 ) ;
196-
197- let prev = self
198- . typeck_results
199- . borrow_mut ( )
200- . hidden_types
201- . insert ( opaque_type_key. def_id , hidden_type) ;
202- assert ! ( prev. is_none( ) ) ;
203- UsageKind :: HasDefiningUse
204- }
205-
206- fn apply_definition_site_hidden_types (
207- & mut self ,
208- opaque_types : & [ ( OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > ) ] ,
209- ) {
210- let tcx = self . tcx ;
211- for & ( key, hidden_type) in opaque_types {
212- let expected = * self . typeck_results . borrow_mut ( ) . hidden_types . get ( & key. def_id ) . unwrap ( ) ;
213-
214- let expected = EarlyBinder :: bind ( expected. ty ) . instantiate ( tcx, key. args ) ;
215- self . demand_eqtype ( hidden_type. span , expected, hidden_type. ty ) ;
216- }
241+ UsageKind :: HasDefiningUse ( hidden_type)
217242 }
218243
219244 /// We may in theory add further uses of an opaque after cloning the opaque
0 commit comments