1
+ use rustc_errors:: StashKey ;
1
2
use rustc_hir:: def_id:: LocalDefId ;
2
3
use rustc_hir:: intravisit:: { self , Visitor } ;
3
4
use rustc_hir:: { self as hir, Expr , ImplItem , Item , Node , TraitItem } ;
@@ -210,12 +211,40 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
210
211
def_id : LocalDefId ,
211
212
owner_def_id : LocalDefId ,
212
213
) -> Ty < ' _ > {
213
- let concrete = tcx. mir_borrowck ( owner_def_id) . concrete_opaque_types . get ( & def_id ) . copied ( ) ;
214
+ let tables = tcx. typeck ( owner_def_id) ;
214
215
215
- if let Some ( concrete) = concrete {
216
+ // Check that all of the opaques we inferred during HIR are compatible.
217
+ // FIXME: We explicitly don't check that the types inferred during HIR
218
+ // typeck are compatible with the one that we infer during borrowck,
219
+ // because that one actually sometimes has consts evaluated eagerly so
220
+ // using strict type equality will fail.
221
+ let mut hir_opaque_ty: Option < ty:: OpaqueHiddenType < ' tcx > > = None ;
222
+ if tables. tainted_by_errors . is_none ( ) {
223
+ for ( & opaque_type_key, & hidden_type) in & tables. concrete_opaque_types {
224
+ if opaque_type_key. def_id != def_id {
225
+ continue ;
226
+ }
227
+ let concrete_type = tcx. erase_regions (
228
+ hidden_type. remap_generic_params_to_declaration_params ( opaque_type_key, tcx, true ) ,
229
+ ) ;
230
+ if let Some ( prev) = & mut hir_opaque_ty {
231
+ if concrete_type. ty != prev. ty && !( concrete_type, prev. ty ) . references_error ( ) {
232
+ prev. report_mismatch ( & concrete_type, def_id, tcx) . stash (
233
+ tcx. def_span ( opaque_type_key. def_id ) ,
234
+ StashKey :: OpaqueHiddenTypeMismatch ,
235
+ ) ;
236
+ }
237
+ } else {
238
+ hir_opaque_ty = Some ( concrete_type) ;
239
+ }
240
+ }
241
+ }
242
+
243
+ let mir_opaque_ty = tcx. mir_borrowck ( owner_def_id) . concrete_opaque_types . get ( & def_id) . copied ( ) ;
244
+ if let Some ( mir_opaque_ty) = mir_opaque_ty {
216
245
let scope = tcx. hir ( ) . local_def_id_to_hir_id ( owner_def_id) ;
217
246
debug ! ( ?scope) ;
218
- let mut locator = RpitConstraintChecker { def_id, tcx, found : concrete } ;
247
+ let mut locator = RpitConstraintChecker { def_id, tcx, found : mir_opaque_ty } ;
219
248
220
249
match tcx. hir ( ) . get ( scope) {
221
250
Node :: Item ( it) => intravisit:: walk_item ( & mut locator, it) ,
@@ -224,38 +253,16 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
224
253
other => bug ! ( "{:?} is not a valid scope for an opaque type item" , other) ,
225
254
}
226
255
227
- concrete . ty
256
+ mir_opaque_ty . ty
228
257
} else {
229
- let tables = tcx. typeck ( owner_def_id) ;
230
258
if let Some ( guar) = tables. tainted_by_errors {
231
- // Some error in the
232
- // owner fn prevented us from populating
259
+ // Some error in the owner fn prevented us from populating
233
260
// the `concrete_opaque_types` table.
234
261
tcx. ty_error ( guar)
235
262
} else {
236
263
// 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
264
+ if let Some ( hir_opaque_ty) = hir_opaque_ty {
265
+ hir_opaque_ty. ty
259
266
} else {
260
267
// We failed to resolve the opaque type or it
261
268
// resolves to itself. We interpret this as the
0 commit comments