Rollup merge of #148170 - lcnr:opaques-early-binder, r=BoxyUwU

split definition and use site hidden tys

Tracking this implicitly is kinda messy and easy to get wrong.

r? ``@BoxyUwU``
This commit is contained in:
Matthias Krüger 2025-11-02 09:10:36 +01:00 committed by GitHub
commit 8e14ab7e59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 236 additions and 182 deletions

View file

@ -119,7 +119,7 @@ pub fn provide(providers: &mut Providers) {
fn mir_borrowck(
tcx: TyCtxt<'_>,
def: LocalDefId,
) -> Result<&DefinitionSiteHiddenTypes<'_>, ErrorGuaranteed> {
) -> Result<&FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'_>>, ErrorGuaranteed> {
assert!(!tcx.is_typeck_child(def.to_def_id()));
let (input_body, _) = tcx.mir_promoted(def);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
@ -130,7 +130,7 @@ fn mir_borrowck(
Err(guar)
} else if input_body.should_skip() {
debug!("Skipping borrowck because of injected body");
let opaque_types = DefinitionSiteHiddenTypes(Default::default());
let opaque_types = Default::default();
Ok(tcx.arena.alloc(opaque_types))
} else {
let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None);

View file

@ -8,11 +8,11 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, OpaqueTypeStorageEntries};
use rustc_infer::traits::ObligationCause;
use rustc_macros::extension;
use rustc_middle::mir::{Body, ConstraintCategory, DefinitionSiteHiddenTypes};
use rustc_middle::mir::{Body, ConstraintCategory};
use rustc_middle::ty::{
self, DefiningScopeKind, EarlyBinder, FallibleTypeFolder, GenericArg, GenericArgsRef,
OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable,
TypeSuperFoldable, TypeVisitableExt, fold_regions,
self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg,
GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt,
TypeFoldable, TypeSuperFoldable, TypeVisitableExt, fold_regions,
};
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_span::Span;
@ -48,7 +48,7 @@ pub(crate) enum DeferredOpaqueTypeError<'tcx> {
/// The opaque type.
opaque_type_key: OpaqueTypeKey<'tcx>,
/// The hidden type containing the member region.
hidden_type: OpaqueHiddenType<'tcx>,
hidden_type: ProvisionalHiddenType<'tcx>,
/// The unexpected region.
member_region: Region<'tcx>,
},
@ -67,7 +67,7 @@ pub(crate) fn clone_and_resolve_opaque_types<'tcx>(
infcx: &BorrowckInferCtxt<'tcx>,
universal_region_relations: &Frozen<UniversalRegionRelations<'tcx>>,
constraints: &mut MirTypeckRegionConstraints<'tcx>,
) -> (OpaqueTypeStorageEntries, Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>) {
) -> (OpaqueTypeStorageEntries, Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>) {
let opaque_types = infcx.clone_opaque_types();
let opaque_types_storage_num_entries = infcx.inner.borrow_mut().opaque_types().num_entries();
let opaque_types = opaque_types
@ -131,27 +131,26 @@ fn nll_var_to_universal_region<'tcx>(
/// and errors if we end up with distinct hidden types.
fn add_hidden_type<'tcx>(
tcx: TyCtxt<'tcx>,
hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
def_id: LocalDefId,
hidden_ty: OpaqueHiddenType<'tcx>,
hidden_ty: ty::DefinitionSiteHiddenType<'tcx>,
) {
// Sometimes two opaque types are the same only after we remap the generic parameters
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to
// `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we
// only know that once we convert the generic parameters to those of the opaque type.
if let Some(prev) = hidden_types.0.get_mut(&def_id) {
if prev.ty != hidden_ty.ty {
let guar = hidden_ty.ty.error_reported().err().unwrap_or_else(|| {
let (Ok(e) | Err(e)) = prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit());
e
});
prev.ty = Ty::new_error(tcx, guar);
if let Some(prev) = hidden_types.get_mut(&def_id) {
if prev.ty == hidden_ty.ty {
// Pick a better span if there is one.
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
prev.span = prev.span.substitute_dummy(hidden_ty.span);
} else {
let (Ok(guar) | Err(guar)) =
prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit());
*prev = ty::DefinitionSiteHiddenType::new_error(tcx, guar);
}
// Pick a better span if there is one.
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
prev.span = prev.span.substitute_dummy(hidden_ty.span);
} else {
hidden_types.0.insert(def_id, hidden_ty);
hidden_types.insert(def_id, hidden_ty);
}
}
@ -162,7 +161,7 @@ struct DefiningUse<'tcx> {
/// to interact with code outside of `rustc_borrowck`.
opaque_type_key: OpaqueTypeKey<'tcx>,
arg_regions: Vec<RegionVid>,
hidden_type: OpaqueHiddenType<'tcx>,
hidden_type: ProvisionalHiddenType<'tcx>,
}
/// This computes the actual hidden types of the opaque types and maps them to their
@ -181,8 +180,8 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>(
universal_region_relations: &Frozen<UniversalRegionRelations<'tcx>>,
constraints: &MirTypeckRegionConstraints<'tcx>,
location_map: Rc<DenseLocationMap>,
hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)],
) -> Vec<DeferredOpaqueTypeError<'tcx>> {
let mut errors = Vec::new();
// When computing the hidden type we need to track member constraints.
@ -216,8 +215,8 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>(
#[instrument(level = "debug", skip_all, ret)]
fn collect_defining_uses<'tcx>(
rcx: &mut RegionCtxt<'_, 'tcx>,
hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)],
errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
) -> Vec<DefiningUse<'tcx>> {
let infcx = rcx.infcx;
@ -240,7 +239,7 @@ fn collect_defining_uses<'tcx>(
infcx.tcx,
hidden_types,
opaque_type_key.def_id,
OpaqueHiddenType::new_error(infcx.tcx, guar),
DefinitionSiteHiddenType::new_error(infcx.tcx, guar),
),
_ => debug!(?non_nll_opaque_type_key, ?err, "ignoring non-defining use"),
}
@ -276,7 +275,7 @@ fn collect_defining_uses<'tcx>(
#[instrument(level = "debug", skip(rcx, hidden_types, defining_uses, errors))]
fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
rcx: &RegionCtxt<'_, 'tcx>,
hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
defining_uses: &[DefiningUse<'tcx>],
errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
) {
@ -303,21 +302,20 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
hidden_type.span,
"opaque type with non-universal region args",
);
ty::OpaqueHiddenType::new_error(tcx, guar)
ty::ProvisionalHiddenType::new_error(tcx, guar)
}
};
// Now that we mapped the member regions to their final value,
// map the arguments of the opaque type key back to the parameters
// of the opaque type definition.
let ty = infcx
let hidden_type = infcx
.infer_opaque_definition_from_instantiation(opaque_type_key, hidden_type)
.unwrap_or_else(|_| {
Ty::new_error_with_message(
rcx.infcx.tcx,
hidden_type.span,
"deferred invalid opaque type args",
)
let guar = tcx
.dcx()
.span_delayed_bug(hidden_type.span, "deferred invalid opaque type args");
DefinitionSiteHiddenType::new_error(tcx, guar)
});
// Sometimes, when the hidden type is an inference variable, it can happen that
@ -325,7 +323,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
// writeback.
if !rcx.infcx.tcx.use_typing_mode_borrowck() {
if let ty::Alias(ty::Opaque, alias_ty) = ty.kind()
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.skip_binder().kind()
&& alias_ty.def_id == opaque_type_key.def_id.to_def_id()
&& alias_ty.args == opaque_type_key.args
{
@ -357,12 +355,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
},
));
}
add_hidden_type(
tcx,
hidden_types,
opaque_type_key.def_id,
OpaqueHiddenType { span: hidden_type.span, ty },
);
add_hidden_type(tcx, hidden_types, opaque_type_key.def_id, hidden_type);
}
}
@ -495,14 +488,13 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
region_bound_pairs: &RegionBoundPairs<'tcx>,
known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>],
constraints: &mut MirTypeckRegionConstraints<'tcx>,
hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)],
) -> Vec<DeferredOpaqueTypeError<'tcx>> {
let tcx = infcx.tcx;
let mut errors = Vec::new();
for &(key, hidden_type) in opaque_types {
let Some(expected) = hidden_types.0.get(&key.def_id).map(|ty| EarlyBinder::bind(*ty))
else {
let Some(expected) = hidden_types.get(&key.def_id) else {
if !tcx.use_typing_mode_borrowck() {
if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
&& alias_ty.def_id == key.def_id.to_def_id()
@ -521,20 +513,26 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
hidden_type.span,
"non-defining use in the defining scope with no defining uses",
);
add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar));
add_hidden_type(
tcx,
hidden_types,
key.def_id,
DefinitionSiteHiddenType::new_error(tcx, guar),
);
continue;
};
// We erase all non-member region of the opaque and need to treat these as existentials.
let expected = ty::fold_regions(tcx, expected.instantiate(tcx, key.args), |re, _dbi| {
match re.kind() {
ty::ReErased => infcx.next_nll_region_var(
NllRegionVariableOrigin::Existential { name: None },
|| crate::RegionCtxt::Existential(None),
),
_ => re,
}
});
let expected_ty =
ty::fold_regions(tcx, expected.ty.instantiate(tcx, key.args), |re, _dbi| {
match re.kind() {
ty::ReErased => infcx.next_nll_region_var(
NllRegionVariableOrigin::Existential { name: None },
|| crate::RegionCtxt::Existential(None),
),
_ => re,
}
});
// We now simply equate the expected with the actual hidden type.
let locations = Locations::All(hidden_type.span);
@ -555,13 +553,18 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
);
// We need to normalize both types in the old solver before equatingt them.
let actual_ty = ocx.normalize(&cause, infcx.param_env, hidden_type.ty);
let expected_ty = ocx.normalize(&cause, infcx.param_env, expected.ty);
let expected_ty = ocx.normalize(&cause, infcx.param_env, expected_ty);
ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution)
},
"equating opaque types",
),
) {
add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar));
add_hidden_type(
tcx,
hidden_types,
key.def_id,
DefinitionSiteHiddenType::new_error(tcx, guar),
);
}
}
errors
@ -676,8 +679,8 @@ impl<'tcx> InferCtxt<'tcx> {
fn infer_opaque_definition_from_instantiation(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
instantiated_ty: OpaqueHiddenType<'tcx>,
) -> Result<Ty<'tcx>, NonDefiningUseReason<'tcx>> {
instantiated_ty: ProvisionalHiddenType<'tcx>,
) -> Result<ty::DefinitionSiteHiddenType<'tcx>, NonDefiningUseReason<'tcx>> {
opaque_type_has_defining_use_args(
self,
opaque_type_key,
@ -685,15 +688,12 @@ impl<'tcx> InferCtxt<'tcx> {
DefiningScopeKind::MirBorrowck,
)?;
let definition_ty = instantiated_ty
.remap_generic_params_to_declaration_params(
opaque_type_key,
self.tcx,
DefiningScopeKind::MirBorrowck,
)
.ty;
definition_ty.error_reported()?;
let definition_ty = instantiated_ty.remap_generic_params_to_declaration_params(
opaque_type_key,
self.tcx,
DefiningScopeKind::MirBorrowck,
);
definition_ty.ty.skip_binder().error_reported()?;
Ok(definition_ty)
}
}

View file

@ -17,9 +17,8 @@ use crate::region_infer::opaque_types::{
};
use crate::type_check::{Locations, constraint_conversion};
use crate::{
ClosureRegionRequirements, CollectRegionConstraintsResult, DefinitionSiteHiddenTypes,
PropagatedBorrowCheckResults, borrowck_check_region_constraints,
borrowck_collect_region_constraints,
ClosureRegionRequirements, CollectRegionConstraintsResult, PropagatedBorrowCheckResults,
borrowck_check_region_constraints, borrowck_collect_region_constraints,
};
/// The shared context used by both the root as well as all its nested
@ -27,7 +26,7 @@ use crate::{
pub(super) struct BorrowCheckRootCtxt<'tcx> {
pub tcx: TyCtxt<'tcx>,
root_def_id: LocalDefId,
hidden_types: DefinitionSiteHiddenTypes<'tcx>,
hidden_types: FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
/// The region constraints computed by [borrowck_collect_region_constraints]. This uses
/// an [FxIndexMap] to guarantee that iterating over it visits nested bodies before
/// their parents.
@ -72,7 +71,10 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
&self.propagated_borrowck_results[&nested_body_def_id].used_mut_upvars
}
pub(super) fn finalize(self) -> Result<&'tcx DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> {
pub(super) fn finalize(
self,
) -> Result<&'tcx FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>, ErrorGuaranteed>
{
if let Some(guar) = self.tainted_by_errors {
Err(guar)
} else {

View file

@ -430,7 +430,7 @@ fn best_definition_site_of_opaque<'tcx>(
.tcx
.mir_borrowck(item_def_id)
.ok()
.and_then(|opaque_types| opaque_types.0.get(&self.opaque_def_id))
.and_then(|opaque_types| opaque_types.get(&self.opaque_def_id))
{
ControlFlow::Break((hidden_ty.span, item_def_id))
} else {
@ -493,7 +493,7 @@ fn best_definition_site_of_opaque<'tcx>(
fn sanity_check_found_hidden_type<'tcx>(
tcx: TyCtxt<'tcx>,
key: ty::OpaqueTypeKey<'tcx>,
mut ty: ty::OpaqueHiddenType<'tcx>,
mut ty: ty::ProvisionalHiddenType<'tcx>,
) -> Result<(), ErrorGuaranteed> {
if ty.ty.is_ty_var() {
// Nothing was actually constrained.
@ -529,7 +529,7 @@ fn sanity_check_found_hidden_type<'tcx>(
Ok(())
} else {
let span = tcx.def_span(key.def_id);
let other = ty::OpaqueHiddenType { ty: hidden_ty, span };
let other = ty::ProvisionalHiddenType { ty: hidden_ty, span };
Err(ty.build_mismatch_error(&other, tcx)?.emit())
}
}

View file

@ -345,7 +345,7 @@ pub(super) fn type_of_opaque(
def_id: DefId,
) -> Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
if let Some(def_id) = def_id.as_local() {
Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
Ok(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
opaque::find_opaque_ty_constraints_for_tait(
tcx,
@ -378,7 +378,7 @@ pub(super) fn type_of_opaque(
DefiningScopeKind::MirBorrowck,
)
}
}))
})
} else {
// Foreign opaque type will go through the foreign provider
// and load the type from metadata.
@ -390,7 +390,7 @@ pub(super) fn type_of_opaque_hir_typeck(
tcx: TyCtxt<'_>,
def_id: LocalDefId,
) -> ty::EarlyBinder<'_, Ty<'_>> {
ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
opaque::find_opaque_ty_constraints_for_tait(tcx, def_id, DefiningScopeKind::HirTypeck)
}
@ -419,7 +419,7 @@ pub(super) fn type_of_opaque_hir_typeck(
DefiningScopeKind::HirTypeck,
)
}
})
}
}
fn infer_placeholder_type<'tcx>(

View file

@ -3,7 +3,7 @@ use rustc_hir::def_id::LocalDefId;
use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem, def, intravisit};
use rustc_middle::bug;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, DefiningScopeKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{self, DefiningScopeKind, EarlyBinder, Ty, TyCtxt, TypeVisitableExt};
use rustc_trait_selection::opaque_types::report_item_does_not_constrain_error;
use tracing::{debug, instrument, trace};
@ -16,7 +16,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
tcx: TyCtxt<'_>,
def_id: LocalDefId,
opaque_types_from: DefiningScopeKind,
) -> Ty<'_> {
) -> EarlyBinder<'_, Ty<'_>> {
let mut parent_def_id = def_id;
while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy {
// Account for `type Alias = impl Trait<Foo = impl Trait>;` (#116031)
@ -49,7 +49,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
name: tcx.item_ident(parent_def_id.to_def_id()),
what: "impl",
});
Ty::new_error(tcx, guar)
EarlyBinder::bind(Ty::new_error(tcx, guar))
}
}
@ -76,7 +76,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(
tcx: TyCtxt<'_>,
def_id: LocalDefId,
opaque_types_from: DefiningScopeKind,
) -> Ty<'_> {
) -> EarlyBinder<'_, Ty<'_>> {
let mut locator = TaitConstraintLocator { def_id, tcx, found: None, opaque_types_from };
tcx.hir_walk_toplevel_module(&mut locator);
@ -94,7 +94,7 @@ pub(super) fn find_opaque_ty_constraints_for_tait(
name: tcx.item_ident(parent_def_id.to_def_id()),
what: "crate",
});
Ty::new_error(tcx, guar)
EarlyBinder::bind(Ty::new_error(tcx, guar))
}
}
@ -109,18 +109,18 @@ struct TaitConstraintLocator<'tcx> {
/// with the first type that we find, and then later types are
/// checked against it (we also carry the span of that first
/// type).
found: Option<ty::OpaqueHiddenType<'tcx>>,
found: Option<ty::DefinitionSiteHiddenType<'tcx>>,
opaque_types_from: DefiningScopeKind,
}
impl<'tcx> TaitConstraintLocator<'tcx> {
fn insert_found(&mut self, hidden_ty: ty::OpaqueHiddenType<'tcx>) {
fn insert_found(&mut self, hidden_ty: ty::DefinitionSiteHiddenType<'tcx>) {
if let Some(prev) = &mut self.found {
if hidden_ty.ty != prev.ty {
let (Ok(guar) | Err(guar)) =
prev.build_mismatch_error(&hidden_ty, self.tcx).map(|d| d.emit());
prev.ty = Ty::new_error(self.tcx, guar);
*prev = ty::DefinitionSiteHiddenType::new_error(self.tcx, guar);
}
} else {
self.found = Some(hidden_ty);
@ -133,7 +133,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
// with the new solver.
assert!(!self.tcx.next_trait_solver_globally());
let guar = report_item_does_not_constrain_error(self.tcx, item_def_id, self.def_id, None);
self.insert_found(ty::OpaqueHiddenType::new_error(self.tcx, guar));
self.insert_found(ty::DefinitionSiteHiddenType::new_error(self.tcx, guar));
}
#[instrument(skip(self), level = "debug")]
@ -168,7 +168,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
hir_sig.decl.output.span(),
"inferring return types and opaque types do not mix well",
);
self.found = Some(ty::OpaqueHiddenType::new_error(tcx, guar));
self.found = Some(ty::DefinitionSiteHiddenType::new_error(tcx, guar));
return;
}
@ -176,7 +176,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
DefiningScopeKind::HirTypeck => {
let tables = tcx.typeck(item_def_id);
if let Some(guar) = tables.tainted_by_errors {
self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar));
} else if let Some(&hidden_type) = tables.hidden_types.get(&self.def_id) {
self.insert_found(hidden_type);
} else {
@ -184,17 +184,15 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
}
}
DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(item_def_id) {
Err(guar) => self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)),
Err(guar) => self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar)),
Ok(hidden_types) => {
if let Some(&hidden_type) = hidden_types.0.get(&self.def_id) {
if let Some(&hidden_type) = hidden_types.get(&self.def_id) {
debug!(?hidden_type, "found constraint");
self.insert_found(hidden_type);
} else if let Err(guar) = tcx
.type_of_opaque_hir_typeck(self.def_id)
.instantiate_identity()
.error_reported()
} else if let Err(guar) =
tcx.type_of_opaque_hir_typeck(self.def_id).skip_binder().error_reported()
{
self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
self.insert_found(ty::DefinitionSiteHiddenType::new_error(tcx, guar));
} else {
self.non_defining_use_in_defining_scope(item_def_id);
}
@ -241,7 +239,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
def_id: LocalDefId,
owner_def_id: LocalDefId,
opaque_types_from: DefiningScopeKind,
) -> Ty<'tcx> {
) -> EarlyBinder<'tcx, Ty<'tcx>> {
// When an opaque type is stranded, its hidden type cannot be inferred
// so we should not continue.
if !tcx.opaque_types_defined_by(owner_def_id).contains(&def_id) {
@ -249,14 +247,14 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
let guar = tcx
.dcx()
.span_delayed_bug(opaque_type_span, "cannot infer type for stranded opaque type");
return Ty::new_error(tcx, guar);
return EarlyBinder::bind(Ty::new_error(tcx, guar));
}
match opaque_types_from {
DefiningScopeKind::HirTypeck => {
let tables = tcx.typeck(owner_def_id);
if let Some(guar) = tables.tainted_by_errors {
Ty::new_error(tcx, guar)
EarlyBinder::bind(Ty::new_error(tcx, guar))
} else if let Some(hidden_ty) = tables.hidden_types.get(&def_id) {
hidden_ty.ty
} else {
@ -267,24 +265,24 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
// so we can just make the hidden type be `!`.
// For backwards compatibility reasons, we fall back to
// `()` until we the diverging default is changed.
Ty::new_diverging_default(tcx)
EarlyBinder::bind(Ty::new_diverging_default(tcx))
}
}
DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) {
Ok(hidden_types) => {
if let Some(hidden_ty) = hidden_types.0.get(&def_id) {
if let Some(hidden_ty) = hidden_types.get(&def_id) {
hidden_ty.ty
} else {
let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity();
if let Err(guar) = hir_ty.error_reported() {
Ty::new_error(tcx, guar)
let hir_ty = tcx.type_of_opaque_hir_typeck(def_id);
if let Err(guar) = hir_ty.skip_binder().error_reported() {
EarlyBinder::bind(Ty::new_error(tcx, guar))
} else {
assert!(!tcx.next_trait_solver_globally());
hir_ty
}
}
}
Err(guar) => Ty::new_error(tcx, guar),
Err(guar) => EarlyBinder::bind(Ty::new_error(tcx, guar)),
},
}
}

View file

@ -584,8 +584,8 @@ pub(crate) fn method_autoderef_steps<'tcx>(
value: query::MethodAutoderefSteps { predefined_opaques_in_body, self_ty },
} = goal;
for (key, ty) in predefined_opaques_in_body {
let prev =
infcx.register_hidden_type_in_storage(key, ty::OpaqueHiddenType { span: DUMMY_SP, ty });
let prev = infcx
.register_hidden_type_in_storage(key, ty::ProvisionalHiddenType { span: DUMMY_SP, ty });
// It may be possible that two entries in the opaque type storage end up
// with the same key after resolving contained inference variables.
//

View file

@ -1,8 +1,8 @@
use rustc_hir::def::DefKind;
use rustc_infer::traits::ObligationCause;
use rustc_middle::ty::{
self, DefiningScopeKind, EarlyBinder, OpaqueHiddenType, OpaqueTypeKey, TypeVisitableExt,
TypingMode,
self, DefiningScopeKind, DefinitionSiteHiddenType, OpaqueTypeKey, ProvisionalHiddenType,
TypeVisitableExt, TypingMode,
};
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
use rustc_trait_selection::opaque_types::{
@ -57,9 +57,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
#[derive(Copy, Clone, Debug)]
enum UsageKind<'tcx> {
None,
NonDefiningUse(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>),
UnconstrainedHiddenType(OpaqueHiddenType<'tcx>),
HasDefiningUse(OpaqueHiddenType<'tcx>),
NonDefiningUse(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>),
UnconstrainedHiddenType(ProvisionalHiddenType<'tcx>),
HasDefiningUse(DefinitionSiteHiddenType<'tcx>),
}
impl<'tcx> UsageKind<'tcx> {
@ -88,7 +88,7 @@ impl<'tcx> UsageKind<'tcx> {
impl<'tcx> FnCtxt<'_, 'tcx> {
fn compute_definition_site_hidden_types(
&mut self,
mut opaque_types: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>,
mut opaque_types: Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>,
error_on_missing_defining_use: bool,
) {
for entry in opaque_types.iter_mut() {
@ -131,7 +131,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
continue;
}
let expected = EarlyBinder::bind(ty.ty).instantiate(tcx, opaque_type_key.args);
let expected = ty.ty.instantiate(tcx, opaque_type_key.args);
self.demand_eqtype(hidden_type.span, expected, hidden_type.ty);
}
@ -191,7 +191,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
self.typeck_results
.borrow_mut()
.hidden_types
.insert(def_id, OpaqueHiddenType::new_error(tcx, guar));
.insert(def_id, DefinitionSiteHiddenType::new_error(tcx, guar));
self.set_tainted_by_errors(guar);
}
}
@ -200,7 +200,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
fn consider_opaque_type_use(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
hidden_type: OpaqueHiddenType<'tcx>,
hidden_type: ProvisionalHiddenType<'tcx>,
) -> UsageKind<'tcx> {
if let Err(err) = opaque_type_has_defining_use_args(
&self,
@ -210,7 +210,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
) {
match err {
NonDefiningUseReason::Tainted(guar) => {
return UsageKind::HasDefiningUse(OpaqueHiddenType::new_error(self.tcx, guar));
return UsageKind::HasDefiningUse(DefinitionSiteHiddenType::new_error(
self.tcx, guar,
));
}
_ => return UsageKind::NonDefiningUse(opaque_type_key, hidden_type),
};
@ -230,7 +232,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
Ok(hidden_type) => hidden_type,
Err(errors) => {
let guar = self.err_ctxt().report_fulfillment_errors(errors);
OpaqueHiddenType::new_error(self.tcx, guar)
ProvisionalHiddenType::new_error(self.tcx, guar)
}
};
let hidden_type = hidden_type.remap_generic_params_to_declaration_params(

View file

@ -21,7 +21,7 @@ use rustc_infer::traits::solve::Goal;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::{
self, DefiningScopeKind, OpaqueHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder,
self, DefiningScopeKind, DefinitionSiteHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
fold_regions,
};
@ -550,10 +550,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
fn visit_opaque_types_next(&mut self) {
let mut fcx_typeck_results = self.fcx.typeck_results.borrow_mut();
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
for hidden_ty in fcx_typeck_results.hidden_types.values() {
assert!(!hidden_ty.has_infer());
}
assert_eq!(self.typeck_results.hidden_types.len(), 0);
self.typeck_results.hidden_types = mem::take(&mut fcx_typeck_results.hidden_types);
}
@ -589,7 +585,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
) {
self.typeck_results.hidden_types.insert(
opaque_type_key.def_id,
ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)),
ty::DefinitionSiteHiddenType::new_error(tcx, err.report(self.fcx)),
);
}
@ -603,15 +599,16 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
self.typeck_results.hidden_types.insert(opaque_type_key.def_id, hidden_type)
{
let entry =
&mut self.typeck_results.hidden_types.get_mut(&opaque_type_key.def_id).unwrap();
self.typeck_results.hidden_types.get_mut(&opaque_type_key.def_id).unwrap();
if prev.ty != hidden_type.ty {
if let Some(guar) = self.typeck_results.tainted_by_errors {
entry.ty = Ty::new_error(tcx, guar);
let guar = if let Some(guar) = self.typeck_results.tainted_by_errors {
guar
} else {
let (Ok(guar) | Err(guar)) =
prev.build_mismatch_error(&hidden_type, tcx).map(|d| d.emit());
entry.ty = Ty::new_error(tcx, guar);
}
guar
};
*entry = DefinitionSiteHiddenType::new_error(tcx, guar);
}
// Pick a better span if there is one.
@ -627,6 +624,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
.filter(|&(&def_id, hidden_ty)| {
hidden_ty
.ty
.instantiate_identity()
.visit_with(&mut HasRecursiveOpaque {
def_id,
seen: Default::default(),
@ -646,7 +644,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
.emit();
self.typeck_results
.hidden_types
.insert(def_id, OpaqueHiddenType { span, ty: Ty::new_error(tcx, guar) });
.insert(def_id, DefinitionSiteHiddenType::new_error(tcx, guar));
}
}
@ -1045,7 +1043,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
struct HasRecursiveOpaque<'a, 'tcx> {
def_id: LocalDefId,
seen: FxHashSet<LocalDefId>,
opaques: &'a FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
opaques: &'a FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
tcx: TyCtxt<'tcx>,
}
@ -1063,9 +1061,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasRecursiveOpaque<'_, 'tcx> {
if self.seen.insert(def_id)
&& let Some(hidden_ty) = self.opaques.get(&def_id)
{
ty::EarlyBinder::bind(hidden_ty.ty)
.instantiate(self.tcx, alias_ty.args)
.visit_with(self)?;
hidden_ty.ty.instantiate(self.tcx, alias_ty.args).visit_with(self)?;
}
}

View file

@ -314,7 +314,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
) -> Option<Ty<'tcx>> {
self.register_hidden_type_in_storage(
opaque_type_key,
ty::OpaqueHiddenType { span, ty: hidden_ty },
ty::ProvisionalHiddenType { span, ty: hidden_ty },
)
}
fn add_duplicate_opaque_type(
@ -326,7 +326,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
self.inner
.borrow_mut()
.opaque_types()
.add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty })
.add_duplicate(opaque_type_key, ty::ProvisionalHiddenType { span, ty: hidden_ty })
}
fn reset_opaque_types(&self) {

View file

@ -28,7 +28,7 @@ use rustc_middle::traits::solve::Goal;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{
self, BoundVarReplacerDelegate, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs,
GenericArgsRef, GenericParamDefKind, InferConst, IntVid, OpaqueHiddenType, OpaqueTypeKey,
GenericArgsRef, GenericParamDefKind, InferConst, IntVid, OpaqueTypeKey, ProvisionalHiddenType,
PseudoCanonicalInput, Term, TermKind, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder,
TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions,
};
@ -978,12 +978,12 @@ impl<'tcx> InferCtxt<'tcx> {
}
#[instrument(level = "debug", skip(self), ret)]
pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
pub fn take_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
self.inner.borrow_mut().opaque_type_storage.take_opaque_types().collect()
}
#[instrument(level = "debug", skip(self), ret)]
pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
pub fn clone_opaque_types(&self) -> Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
self.inner.borrow_mut().opaque_type_storage.iter_opaque_types().collect()
}

View file

@ -5,7 +5,7 @@ use rustc_middle::traits::ObligationCause;
use rustc_middle::traits::solve::Goal;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{
self, BottomUpFolder, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
self, BottomUpFolder, OpaqueTypeKey, ProvisionalHiddenType, Ty, TyCtxt, TypeFoldable,
TypeVisitableExt,
};
use rustc_span::Span;
@ -199,7 +199,7 @@ impl<'tcx> InferCtxt<'tcx> {
pub fn register_hidden_type_in_storage(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
hidden_ty: OpaqueHiddenType<'tcx>,
hidden_ty: ProvisionalHiddenType<'tcx>,
) -> Option<Ty<'tcx>> {
self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty)
}
@ -237,7 +237,7 @@ impl<'tcx> InferCtxt<'tcx> {
.inner
.borrow_mut()
.opaque_types()
.register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span });
.register(opaque_type_key, ProvisionalHiddenType { ty: hidden_ty, span });
if let Some(prev) = prev {
goals.extend(
self.at(&ObligationCause::dummy_with_span(span), param_env)
@ -253,7 +253,7 @@ impl<'tcx> InferCtxt<'tcx> {
.inner
.borrow_mut()
.opaque_types()
.register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span });
.register(opaque_type_key, ProvisionalHiddenType { ty: hidden_ty, span });
// We either equate the new hidden type with the previous entry or with the type
// inferred by HIR typeck.

View file

@ -3,15 +3,15 @@ use std::ops::Deref;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::undo_log::UndoLogs;
use rustc_middle::bug;
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
use rustc_middle::ty::{self, OpaqueTypeKey, ProvisionalHiddenType, Ty};
use tracing::instrument;
use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
#[derive(Default, Debug, Clone)]
pub struct OpaqueTypeStorage<'tcx> {
opaque_types: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>,
opaque_types: FxIndexMap<OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>>,
duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>,
}
/// The number of entries in the opaque type storage at a given point.
@ -35,7 +35,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
pub(crate) fn remove(
&mut self,
key: OpaqueTypeKey<'tcx>,
prev: Option<OpaqueHiddenType<'tcx>>,
prev: Option<ProvisionalHiddenType<'tcx>>,
) {
if let Some(prev) = prev {
*self.opaque_types.get_mut(&key).unwrap() = prev;
@ -60,7 +60,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
pub(crate) fn take_opaque_types(
&mut self,
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries))
}
@ -75,7 +75,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
pub fn opaque_types_added_since(
&self,
prev_entries: OpaqueTypeStorageEntries,
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
self.opaque_types
.iter()
.skip(prev_entries.opaque_types)
@ -90,7 +90,7 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
/// to also consider duplicate entries.
pub fn iter_lookup_table(
&self,
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
self.opaque_types.iter().map(|(k, v)| (*k, *v))
}
@ -101,13 +101,13 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
/// accesses them.
pub fn iter_duplicate_entries(
&self,
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
self.duplicate_entries.iter().copied()
}
pub fn iter_opaque_types(
&self,
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
opaque_types.iter().map(|(k, v)| (*k, *v)).chain(duplicate_entries.iter().copied())
}
@ -146,7 +146,7 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
pub fn register(
&mut self,
key: OpaqueTypeKey<'tcx>,
hidden_type: OpaqueHiddenType<'tcx>,
hidden_type: ProvisionalHiddenType<'tcx>,
) -> Option<Ty<'tcx>> {
if let Some(entry) = self.storage.opaque_types.get_mut(&key) {
let prev = std::mem::replace(entry, hidden_type);
@ -158,7 +158,11 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
None
}
pub fn add_duplicate(&mut self, key: OpaqueTypeKey<'tcx>, hidden_type: OpaqueHiddenType<'tcx>) {
pub fn add_duplicate(
&mut self,
key: OpaqueTypeKey<'tcx>,
hidden_type: ProvisionalHiddenType<'tcx>,
) {
self.storage.duplicate_entries.push((key, hidden_type));
self.undo_log.push(UndoLog::DuplicateOpaqueType);
}

View file

@ -3,7 +3,7 @@ use std::marker::PhantomData;
use rustc_data_structures::undo_log::{Rollback, UndoLogs};
use rustc_data_structures::{snapshot_vec as sv, unify as ut};
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey};
use rustc_middle::ty::{self, OpaqueTypeKey, ProvisionalHiddenType};
use tracing::debug;
use crate::infer::unify_key::{ConstVidKey, RegionVidKey};
@ -19,7 +19,7 @@ pub struct Snapshot<'tcx> {
#[derive(Clone)]
pub(crate) enum UndoLog<'tcx> {
DuplicateOpaqueType,
OpaqueTypes(OpaqueTypeKey<'tcx>, Option<OpaqueHiddenType<'tcx>>),
OpaqueTypes(OpaqueTypeKey<'tcx>, Option<ProvisionalHiddenType<'tcx>>),
TypeVariables(type_variable::UndoLog<'tcx>),
ConstUnificationTable(sv::UndoLog<ut::Delegate<ConstVidKey<'tcx>>>),
IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),

View file

@ -27,7 +27,10 @@ macro_rules! arena_types {
rustc_middle::mir::Body<'tcx>
>,
[decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>,
[decode] borrowck_result: rustc_middle::mir::DefinitionSiteHiddenTypes<'tcx>,
[decode] borrowck_result: rustc_data_structures::fx::FxIndexMap<
rustc_hir::def_id::LocalDefId,
rustc_middle::ty::DefinitionSiteHiddenType<'tcx>,
>,
[] resolver: rustc_data_structures::steal::Steal<(
rustc_middle::ty::ResolverAstLowering,
std::sync::Arc<rustc_ast::Crate>,

View file

@ -3,16 +3,14 @@
use std::fmt::{self, Debug};
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::LocalDefId;
use rustc_index::IndexVec;
use rustc_index::bit_set::BitMatrix;
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
use rustc_span::{Span, Symbol};
use super::{ConstValue, SourceInfo};
use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty};
use crate::ty::{self, CoroutineArgsExt, Ty};
rustc_index::newtype_index! {
#[derive(HashStable)]
@ -84,11 +82,6 @@ impl Debug for CoroutineLayout<'_> {
}
}
/// All the opaque types that have had their hidden type fully computed.
/// Unlike the value in `TypeckResults`, this has unerased regions.
#[derive(Default, Debug, TyEncodable, TyDecodable, HashStable)]
pub struct DefinitionSiteHiddenTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>);
/// The result of the `mir_const_qualif` query.
///
/// Each field (except `tainted_by_errors`) corresponds to an implementer of the `Qualif` trait in

View file

@ -1244,7 +1244,10 @@ rustc_queries! {
/// Borrow-checks the given typeck root, e.g. functions, const/static items,
/// and its children, e.g. closures, inline consts.
query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> {
query mir_borrowck(key: LocalDefId) -> Result<
&'tcx FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
ErrorGuaranteed
> {
desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) }
}

View file

@ -725,7 +725,7 @@ impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
}
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
pub struct OpaqueHiddenType<'tcx> {
pub struct ProvisionalHiddenType<'tcx> {
/// The span of this particular definition of the opaque type. So
/// for example:
///
@ -767,9 +767,9 @@ pub enum DefiningScopeKind {
MirBorrowck,
}
impl<'tcx> OpaqueHiddenType<'tcx> {
pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> OpaqueHiddenType<'tcx> {
OpaqueHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) }
impl<'tcx> ProvisionalHiddenType<'tcx> {
pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> ProvisionalHiddenType<'tcx> {
ProvisionalHiddenType { span: DUMMY_SP, ty: Ty::new_error(tcx, guar) }
}
pub fn build_mismatch_error(
@ -798,7 +798,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
opaque_type_key: OpaqueTypeKey<'tcx>,
tcx: TyCtxt<'tcx>,
defining_scope_kind: DefiningScopeKind,
) -> Self {
) -> DefinitionSiteHiddenType<'tcx> {
let OpaqueTypeKey { def_id, args } = opaque_type_key;
// Use args to build up a reverse map from regions to their
@ -821,15 +821,68 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
//
// We erase regions when doing this during HIR typeck. We manually use `fold_regions`
// here as we do not want to anonymize bound variables.
let this = match defining_scope_kind {
DefiningScopeKind::HirTypeck => fold_regions(tcx, self, |_, _| tcx.lifetimes.re_erased),
DefiningScopeKind::MirBorrowck => self,
let ty = match defining_scope_kind {
DefiningScopeKind::HirTypeck => {
fold_regions(tcx, self.ty, |_, _| tcx.lifetimes.re_erased)
}
DefiningScopeKind::MirBorrowck => self.ty,
};
let result = this.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span));
let result_ty = ty.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span));
if cfg!(debug_assertions) && matches!(defining_scope_kind, DefiningScopeKind::HirTypeck) {
assert_eq!(result.ty, fold_regions(tcx, result.ty, |_, _| tcx.lifetimes.re_erased));
assert_eq!(result_ty, fold_regions(tcx, result_ty, |_, _| tcx.lifetimes.re_erased));
}
result
DefinitionSiteHiddenType { span: self.span, ty: ty::EarlyBinder::bind(result_ty) }
}
}
#[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)]
pub struct DefinitionSiteHiddenType<'tcx> {
/// The span of the definition of the opaque type. So for example:
///
/// ```ignore (incomplete snippet)
/// type Foo = impl Baz;
/// fn bar() -> Foo {
/// // ^^^ This is the span we are looking for!
/// }
/// ```
///
/// In cases where the fn returns `(impl Trait, impl Trait)` or
/// other such combinations, the result is currently
/// over-approximated, but better than nothing.
pub span: Span,
/// The final type of the opaque.
pub ty: ty::EarlyBinder<'tcx, Ty<'tcx>>,
}
impl<'tcx> DefinitionSiteHiddenType<'tcx> {
pub fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> DefinitionSiteHiddenType<'tcx> {
DefinitionSiteHiddenType {
span: DUMMY_SP,
ty: ty::EarlyBinder::bind(Ty::new_error(tcx, guar)),
}
}
pub fn build_mismatch_error(
&self,
other: &Self,
tcx: TyCtxt<'tcx>,
) -> Result<Diag<'tcx>, ErrorGuaranteed> {
let self_ty = self.ty.instantiate_identity();
let other_ty = other.ty.instantiate_identity();
(self_ty, other_ty).error_reported()?;
// Found different concrete types for the opaque type.
let sub_diag = if self.span == other.span {
TypeMismatchReason::ConflictType { span: self.span }
} else {
TypeMismatchReason::PreviousUse { span: self.span }
};
Ok(tcx.dcx().create_err(OpaqueHiddenTypeMismatch {
self_ty,
other_ty,
other_span: other.span,
sub: sub_diag,
}))
}
}

View file

@ -168,7 +168,7 @@ 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).
pub hidden_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
pub hidden_types: FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
/// Tracks the minimum captures required for a closure;
/// see `MinCaptureInformationMap` for more details.

View file

@ -148,7 +148,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
self.typeck_results
.hidden_types
.get(&key.def_id)
.map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
.map(|x| x.ty.instantiate(self.tcx, key.args))
}
// This can take a non-revealed `Ty` because it reveals opaques itself.
pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {