Check that RPITs are compatible with the opaques inferred during HIR typeck too
This commit is contained in:
parent
3d09b990d7
commit
df1c1afdaf
7 changed files with 46 additions and 155 deletions
|
@ -1,3 +1,4 @@
|
|||
use rustc_errors::StashKey;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
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>(
|
|||
def_id: LocalDefId,
|
||||
owner_def_id: LocalDefId,
|
||||
) -> Ty<'_> {
|
||||
let concrete = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied();
|
||||
let tables = tcx.typeck(owner_def_id);
|
||||
|
||||
if let Some(concrete) = concrete {
|
||||
// Check that all of the opaques we inferred during HIR are compatible.
|
||||
// FIXME: We explicitly don't check that the types inferred during HIR
|
||||
// typeck are compatible with the one that we infer during borrowck,
|
||||
// because that one actually sometimes has consts evaluated eagerly so
|
||||
// using strict type equality will fail.
|
||||
let mut hir_opaque_ty: Option<ty::OpaqueHiddenType<'tcx>> = None;
|
||||
if tables.tainted_by_errors.is_none() {
|
||||
for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
|
||||
if opaque_type_key.def_id != def_id {
|
||||
continue;
|
||||
}
|
||||
let concrete_type = tcx.erase_regions(
|
||||
hidden_type.remap_generic_params_to_declaration_params(opaque_type_key, tcx, true),
|
||||
);
|
||||
if let Some(prev) = &mut hir_opaque_ty {
|
||||
if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {
|
||||
prev.report_mismatch(&concrete_type, def_id, tcx).stash(
|
||||
tcx.def_span(opaque_type_key.def_id),
|
||||
StashKey::OpaqueHiddenTypeMismatch,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
hir_opaque_ty = Some(concrete_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mir_opaque_ty = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied();
|
||||
if let Some(mir_opaque_ty) = mir_opaque_ty {
|
||||
let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id);
|
||||
debug!(?scope);
|
||||
let mut locator = RpitConstraintChecker { def_id, tcx, found: concrete };
|
||||
let mut locator = RpitConstraintChecker { def_id, tcx, found: mir_opaque_ty };
|
||||
|
||||
match tcx.hir().get(scope) {
|
||||
Node::Item(it) => intravisit::walk_item(&mut locator, it),
|
||||
|
@ -224,38 +253,16 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
|
|||
other => bug!("{:?} is not a valid scope for an opaque type item", other),
|
||||
}
|
||||
|
||||
concrete.ty
|
||||
mir_opaque_ty.ty
|
||||
} else {
|
||||
let tables = tcx.typeck(owner_def_id);
|
||||
if let Some(guar) = tables.tainted_by_errors {
|
||||
// Some error in the
|
||||
// owner fn prevented us from populating
|
||||
// Some error in the owner fn prevented us from populating
|
||||
// the `concrete_opaque_types` table.
|
||||
tcx.ty_error(guar)
|
||||
} else {
|
||||
// Fall back to the RPIT we inferred during HIR typeck
|
||||
let mut opaque_ty: Option<ty::OpaqueHiddenType<'tcx>> = None;
|
||||
for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types {
|
||||
if opaque_type_key.def_id != def_id {
|
||||
continue;
|
||||
}
|
||||
let concrete_type =
|
||||
tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params(
|
||||
opaque_type_key,
|
||||
tcx,
|
||||
true,
|
||||
));
|
||||
if let Some(prev) = &mut opaque_ty {
|
||||
if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {
|
||||
prev.report_mismatch(&concrete_type, def_id, tcx).emit();
|
||||
}
|
||||
} else {
|
||||
opaque_ty = Some(concrete_type);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(opaque_ty) = opaque_ty {
|
||||
opaque_ty.ty
|
||||
if let Some(hir_opaque_ty) = hir_opaque_ty {
|
||||
hir_opaque_ty.ty
|
||||
} else {
|
||||
// We failed to resolve the opaque type or it
|
||||
// resolves to itself. We interpret this as the
|
||||
|
|
|
@ -155,10 +155,6 @@ pub struct TypeckResults<'tcx> {
|
|||
/// We also store the type here, so that the compiler can use it as a hint
|
||||
/// for figuring out hidden types, even if they are only set in dead code
|
||||
/// (which doesn't show up in MIR).
|
||||
///
|
||||
/// These types are mapped back to the opaque's identity substitutions
|
||||
/// (with erased regions), which is why we don't associated substs with any
|
||||
/// of these usages.
|
||||
pub concrete_opaque_types: FxIndexMap<ty::OpaqueTypeKey<'tcx>, ty::OpaqueHiddenType<'tcx>>,
|
||||
|
||||
/// Tracks the minimum captures required for a closure;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue