split definition and use site hidden tys
This commit is contained in:
parent
23c7bad921
commit
ad20e5c468
14 changed files with 188 additions and 138 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ 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,
|
||||
self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, GenericArg,
|
||||
GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable,
|
||||
TypeSuperFoldable, TypeVisitableExt, fold_regions,
|
||||
};
|
||||
use rustc_mir_dataflow::points::DenseLocationMap;
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +180,7 @@ 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>,
|
||||
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
|
||||
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
|
||||
) -> Vec<DeferredOpaqueTypeError<'tcx>> {
|
||||
let mut errors = Vec::new();
|
||||
|
|
@ -216,7 +215,7 @@ 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>,
|
||||
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
|
||||
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
|
||||
errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
|
||||
) -> Vec<DefiningUse<'tcx>> {
|
||||
|
|
@ -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>>,
|
||||
) {
|
||||
|
|
@ -310,14 +309,13 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
|
|||
// 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>,
|
||||
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
|
||||
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'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
|
||||
|
|
@ -677,7 +680,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
&self,
|
||||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||
instantiated_ty: OpaqueHiddenType<'tcx>,
|
||||
) -> Result<Ty<'tcx>, NonDefiningUseReason<'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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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>(
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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, OpaqueHiddenType, OpaqueTypeKey,
|
||||
TypeVisitableExt, TypingMode,
|
||||
};
|
||||
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_trait_selection::opaque_types::{
|
||||
|
|
@ -59,7 +59,7 @@ enum UsageKind<'tcx> {
|
|||
None,
|
||||
NonDefiningUse(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>),
|
||||
UnconstrainedHiddenType(OpaqueHiddenType<'tcx>),
|
||||
HasDefiningUse(OpaqueHiddenType<'tcx>),
|
||||
HasDefiningUse(DefinitionSiteHiddenType<'tcx>),
|
||||
}
|
||||
|
||||
impl<'tcx> UsageKind<'tcx> {
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,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.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue