@@ -59,7 +59,20 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
5959 }
6060 }
6161
62- let Some ( hidden) = locator. found else {
62+ if let Some ( hidden) = locator. found {
63+ // Only check against typeck if we didn't already error
64+ if !hidden. ty . references_error ( ) {
65+ for concrete_type in locator. typeck_types {
66+ if concrete_type. ty != tcx. erase_regions ( hidden. ty )
67+ && !( concrete_type, hidden) . references_error ( )
68+ {
69+ hidden. report_mismatch ( & concrete_type, def_id, tcx) . emit ( ) ;
70+ }
71+ }
72+ }
73+
74+ hidden. ty
75+ } else {
6376 let reported = tcx. sess . emit_err ( UnconstrainedOpaqueType {
6477 span : tcx. def_span ( def_id) ,
6578 name : tcx. item_name ( tcx. local_parent ( def_id) . to_def_id ( ) ) ,
@@ -70,21 +83,8 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local
7083 _ => "item" ,
7184 } ,
7285 } ) ;
73- return tcx. ty_error ( reported) ;
74- } ;
75-
76- // Only check against typeck if we didn't already error
77- if !hidden. ty . references_error ( ) {
78- for concrete_type in locator. typeck_types {
79- if concrete_type. ty != tcx. erase_regions ( hidden. ty )
80- && !( concrete_type, hidden) . references_error ( )
81- {
82- hidden. report_mismatch ( & concrete_type, def_id, tcx) . emit ( ) ;
83- }
84- }
86+ tcx. ty_error ( reported)
8587 }
86-
87- hidden. ty
8888}
8989
9090struct TaitConstraintLocator < ' tcx > {
@@ -130,13 +130,28 @@ impl TaitConstraintLocator<'_> {
130130 self . found = Some ( ty:: OpaqueHiddenType { span : DUMMY_SP , ty : self . tcx . ty_error ( guar) } ) ;
131131 return ;
132132 }
133- let Some ( & typeck_hidden_ty) = tables. concrete_opaque_types . get ( & self . def_id ) else {
133+
134+ let mut constrained = false ;
135+ for ( & opaque_type_key, & hidden_type) in & tables. concrete_opaque_types {
136+ if opaque_type_key. def_id != self . def_id {
137+ continue ;
138+ }
139+ constrained = true ;
140+ let concrete_type =
141+ self . tcx . erase_regions ( hidden_type. remap_generic_params_to_declaration_params (
142+ opaque_type_key,
143+ self . tcx ,
144+ true ,
145+ ) ) ;
146+ if self . typeck_types . iter ( ) . all ( |prev| prev. ty != concrete_type. ty ) {
147+ self . typeck_types . push ( concrete_type) ;
148+ }
149+ }
150+
151+ if !constrained {
134152 debug ! ( "no constraints in typeck results" ) ;
135153 return ;
136154 } ;
137- if self . typeck_types . iter ( ) . all ( |prev| prev. ty != typeck_hidden_ty. ty ) {
138- self . typeck_types . push ( typeck_hidden_ty) ;
139- }
140155
141156 // Use borrowck to get the type with unerased regions.
142157 let concrete_opaque_types = & self . tcx . mir_borrowck ( item_def_id) . concrete_opaque_types ;
@@ -190,8 +205,8 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
190205 }
191206}
192207
193- pub ( super ) fn find_opaque_ty_constraints_for_rpit (
194- tcx : TyCtxt < ' _ > ,
208+ pub ( super ) fn find_opaque_ty_constraints_for_rpit < ' tcx > (
209+ tcx : TyCtxt < ' tcx > ,
195210 def_id : LocalDefId ,
196211 owner_def_id : LocalDefId ,
197212) -> Ty < ' _ > {
@@ -208,27 +223,50 @@ pub(super) fn find_opaque_ty_constraints_for_rpit(
208223 Node :: TraitItem ( it) => intravisit:: walk_trait_item ( & mut locator, it) ,
209224 other => bug ! ( "{:?} is not a valid scope for an opaque type item" , other) ,
210225 }
211- }
212226
213- concrete. map ( |concrete| concrete. ty ) . unwrap_or_else ( || {
214- let table = tcx. typeck ( owner_def_id) ;
215- if let Some ( guar) = table. tainted_by_errors {
227+ concrete. ty
228+ } else {
229+ let tables = tcx. typeck ( owner_def_id) ;
230+ if let Some ( guar) = tables. tainted_by_errors {
216231 // Some error in the
217232 // owner fn prevented us from populating
218233 // the `concrete_opaque_types` table.
219234 tcx. ty_error ( guar)
220235 } else {
221- table. concrete_opaque_types . get ( & def_id) . map ( |ty| ty. ty ) . unwrap_or_else ( || {
236+ // Fall back to the RPIT we inferred during HIR typeck
237+ let mut opaque_ty: Option < ty:: OpaqueHiddenType < ' tcx > > = None ;
238+ for ( & opaque_type_key, & hidden_type) in & tables. concrete_opaque_types {
239+ if opaque_type_key. def_id != def_id {
240+ continue ;
241+ }
242+ let concrete_type =
243+ tcx. erase_regions ( hidden_type. remap_generic_params_to_declaration_params (
244+ opaque_type_key,
245+ tcx,
246+ true ,
247+ ) ) ;
248+ if let Some ( prev) = & mut opaque_ty {
249+ if concrete_type. ty != prev. ty && !( concrete_type, prev. ty ) . references_error ( ) {
250+ prev. report_mismatch ( & concrete_type, def_id, tcx) . emit ( ) ;
251+ }
252+ } else {
253+ opaque_ty = Some ( concrete_type) ;
254+ }
255+ }
256+
257+ if let Some ( opaque_ty) = opaque_ty {
258+ opaque_ty. ty
259+ } else {
222260 // We failed to resolve the opaque type or it
223261 // resolves to itself. We interpret this as the
224262 // no values of the hidden type ever being constructed,
225263 // so we can just make the hidden type be `!`.
226264 // For backwards compatibility reasons, we fall back to
227265 // `()` until we the diverging default is changed.
228266 tcx. mk_diverging_default ( )
229- } )
267+ }
230268 }
231- } )
269+ }
232270}
233271
234272struct RpitConstraintChecker < ' tcx > {
0 commit comments