Rename various "concrete opaque type" terminology to say "hidden type"
This commit is contained in:
parent
ade84871f7
commit
4d41177513
15 changed files with 82 additions and 116 deletions
|
|
@ -116,10 +116,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
/// Provider for `query mir_borrowck`. Similar to `typeck`, this must
|
||||
/// only be called for typeck roots which will then borrowck all
|
||||
/// nested bodies as well.
|
||||
fn mir_borrowck(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: LocalDefId,
|
||||
) -> Result<&ConcreteOpaqueTypes<'_>, ErrorGuaranteed> {
|
||||
fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> Result<&HiddenTypes<'_>, 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 +127,7 @@ fn mir_borrowck(
|
|||
Err(guar)
|
||||
} else if input_body.should_skip() {
|
||||
debug!("Skipping borrowck because of injected body");
|
||||
let opaque_types = ConcreteOpaqueTypes(Default::default());
|
||||
let opaque_types = HiddenTypes(Default::default());
|
||||
Ok(tcx.arena.alloc(opaque_types))
|
||||
} else {
|
||||
let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None);
|
||||
|
|
|
|||
|
|
@ -1382,10 +1382,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
}
|
||||
|
||||
/// The constraints we get from equating the hidden type of each use of an opaque
|
||||
/// with its final concrete type may end up getting preferred over other, potentially
|
||||
/// with its final hidden type may end up getting preferred over other, potentially
|
||||
/// longer constraint paths.
|
||||
///
|
||||
/// Given that we compute the final concrete type by relying on this existing constraint
|
||||
/// Given that we compute the final hidden type by relying on this existing constraint
|
||||
/// path, this can easily end up hiding the actual reason for why we require these regions
|
||||
/// to be equal.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ 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, ConcreteOpaqueTypes, ConstraintCategory};
|
||||
use rustc_middle::mir::{Body, ConstraintCategory, HiddenTypes};
|
||||
use rustc_middle::ty::{
|
||||
self, DefiningScopeKind, EarlyBinder, FallibleTypeFolder, GenericArg, GenericArgsRef,
|
||||
OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable,
|
||||
|
|
@ -129,9 +129,9 @@ fn nll_var_to_universal_region<'tcx>(
|
|||
/// Collect all defining uses of opaque types inside of this typeck root. This
|
||||
/// expects the hidden type to be mapped to the definition parameters of the opaque
|
||||
/// and errors if we end up with distinct hidden types.
|
||||
fn add_concrete_opaque_type<'tcx>(
|
||||
fn add_hidden_type<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
|
||||
hidden_types: &mut HiddenTypes<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
hidden_ty: OpaqueHiddenType<'tcx>,
|
||||
) {
|
||||
|
|
@ -139,7 +139,7 @@ fn add_concrete_opaque_type<'tcx>(
|
|||
// 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) = concrete_opaque_types.0.get_mut(&def_id) {
|
||||
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());
|
||||
|
|
@ -151,15 +151,15 @@ fn add_concrete_opaque_type<'tcx>(
|
|||
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
|
||||
prev.span = prev.span.substitute_dummy(hidden_ty.span);
|
||||
} else {
|
||||
concrete_opaque_types.0.insert(def_id, hidden_ty);
|
||||
hidden_types.0.insert(def_id, hidden_ty);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_concrete_opaque_type<'tcx>(
|
||||
concrete_opaque_types: &ConcreteOpaqueTypes<'tcx>,
|
||||
fn get_hidden_type<'tcx>(
|
||||
hidden_types: &HiddenTypes<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) -> Option<EarlyBinder<'tcx, OpaqueHiddenType<'tcx>>> {
|
||||
concrete_opaque_types.0.get(&def_id).map(|ty| EarlyBinder::bind(*ty))
|
||||
hidden_types.0.get(&def_id).map(|ty| EarlyBinder::bind(*ty))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -173,22 +173,22 @@ struct DefiningUse<'tcx> {
|
|||
}
|
||||
|
||||
/// This computes the actual hidden types of the opaque types and maps them to their
|
||||
/// definition sites. Outside of registering the computed concrete types this function
|
||||
/// definition sites. Outside of registering the computed hidden types this function
|
||||
/// does not mutate the current borrowck state.
|
||||
///
|
||||
/// While it may fail to infer the hidden type and return errors, we always apply
|
||||
/// the computed concrete hidden type to all opaque type uses to check whether they
|
||||
/// the computed hidden type to all opaque type uses to check whether they
|
||||
/// are correct. This is necessary to support non-defining uses of opaques in their
|
||||
/// defining scope.
|
||||
///
|
||||
/// It also means that this whole function is not really soundness critical as we
|
||||
/// recheck all uses of the opaques regardless.
|
||||
pub(crate) fn compute_concrete_opaque_types<'tcx>(
|
||||
pub(crate) fn compute_hidden_types<'tcx>(
|
||||
infcx: &BorrowckInferCtxt<'tcx>,
|
||||
universal_region_relations: &Frozen<UniversalRegionRelations<'tcx>>,
|
||||
constraints: &MirTypeckRegionConstraints<'tcx>,
|
||||
location_map: Rc<DenseLocationMap>,
|
||||
concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
|
||||
hidden_types: &mut HiddenTypes<'tcx>,
|
||||
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
|
||||
) -> Vec<DeferredOpaqueTypeError<'tcx>> {
|
||||
let mut errors = Vec::new();
|
||||
|
|
@ -201,8 +201,7 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>(
|
|||
// We start by checking each use of an opaque type during type check and
|
||||
// check whether the generic arguments of the opaque type are fully
|
||||
// universal, if so, it's a defining use.
|
||||
let defining_uses =
|
||||
collect_defining_uses(&mut rcx, concrete_opaque_types, opaque_types, &mut errors);
|
||||
let defining_uses = collect_defining_uses(&mut rcx, hidden_types, opaque_types, &mut errors);
|
||||
|
||||
// We now compute and apply member constraints for all regions in the hidden
|
||||
// types of each defining use. This mutates the region values of the `rcx` which
|
||||
|
|
@ -210,21 +209,16 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>(
|
|||
apply_member_constraints(&mut rcx, &defining_uses);
|
||||
|
||||
// After applying member constraints, we now check whether all member regions ended
|
||||
// up equal to one of their choice regions and compute the actual concrete type of
|
||||
// up equal to one of their choice regions and compute the actual hidden type of
|
||||
// the opaque type definition. This is stored in the `root_cx`.
|
||||
compute_concrete_types_from_defining_uses(
|
||||
&rcx,
|
||||
concrete_opaque_types,
|
||||
&defining_uses,
|
||||
&mut errors,
|
||||
);
|
||||
compute_hidden_types_from_defining_uses(&rcx, hidden_types, &defining_uses, &mut errors);
|
||||
errors
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip_all, ret)]
|
||||
fn collect_defining_uses<'tcx>(
|
||||
rcx: &mut RegionCtxt<'_, 'tcx>,
|
||||
concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
|
||||
hidden_types: &mut HiddenTypes<'tcx>,
|
||||
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
|
||||
errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
|
||||
) -> Vec<DefiningUse<'tcx>> {
|
||||
|
|
@ -244,9 +238,9 @@ fn collect_defining_uses<'tcx>(
|
|||
// with `TypingMode::Borrowck`.
|
||||
if infcx.tcx.use_typing_mode_borrowck() {
|
||||
match err {
|
||||
NonDefiningUseReason::Tainted(guar) => add_concrete_opaque_type(
|
||||
NonDefiningUseReason::Tainted(guar) => add_hidden_type(
|
||||
infcx.tcx,
|
||||
concrete_opaque_types,
|
||||
hidden_types,
|
||||
opaque_type_key.def_id,
|
||||
OpaqueHiddenType::new_error(infcx.tcx, guar),
|
||||
),
|
||||
|
|
@ -277,9 +271,9 @@ fn collect_defining_uses<'tcx>(
|
|||
defining_uses
|
||||
}
|
||||
|
||||
fn compute_concrete_types_from_defining_uses<'tcx>(
|
||||
fn compute_hidden_types_from_defining_uses<'tcx>(
|
||||
rcx: &RegionCtxt<'_, 'tcx>,
|
||||
concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
|
||||
hidden_types: &mut HiddenTypes<'tcx>,
|
||||
defining_uses: &[DefiningUse<'tcx>],
|
||||
errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
|
||||
) {
|
||||
|
|
@ -358,9 +352,9 @@ fn compute_concrete_types_from_defining_uses<'tcx>(
|
|||
},
|
||||
));
|
||||
}
|
||||
add_concrete_opaque_type(
|
||||
add_hidden_type(
|
||||
tcx,
|
||||
concrete_opaque_types,
|
||||
hidden_types,
|
||||
opaque_type_key.def_id,
|
||||
OpaqueHiddenType { span: hidden_type.span, ty },
|
||||
);
|
||||
|
|
@ -489,20 +483,20 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for ToArgRegionsFolder<'_, 'tcx> {
|
|||
///
|
||||
/// It does this by equating the hidden type of each use with the instantiated final
|
||||
/// hidden type of the opaque.
|
||||
pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
|
||||
pub(crate) fn apply_hidden_types<'tcx>(
|
||||
infcx: &BorrowckInferCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
universal_regions: &UniversalRegions<'tcx>,
|
||||
region_bound_pairs: &RegionBoundPairs<'tcx>,
|
||||
known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>],
|
||||
constraints: &mut MirTypeckRegionConstraints<'tcx>,
|
||||
concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
|
||||
hidden_types: &mut HiddenTypes<'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) = get_concrete_opaque_type(concrete_opaque_types, key.def_id) else {
|
||||
let Some(expected) = get_hidden_type(hidden_types, 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,12 +515,7 @@ pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
|
|||
hidden_type.span,
|
||||
"non-defining use in the defining scope with no defining uses",
|
||||
);
|
||||
add_concrete_opaque_type(
|
||||
tcx,
|
||||
concrete_opaque_types,
|
||||
key.def_id,
|
||||
OpaqueHiddenType::new_error(tcx, guar),
|
||||
);
|
||||
add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar));
|
||||
continue;
|
||||
};
|
||||
|
||||
|
|
@ -566,18 +555,13 @@ pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
|
|||
"equating opaque types",
|
||||
),
|
||||
) {
|
||||
add_concrete_opaque_type(
|
||||
tcx,
|
||||
concrete_opaque_types,
|
||||
key.def_id,
|
||||
OpaqueHiddenType::new_error(tcx, guar),
|
||||
);
|
||||
add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar));
|
||||
}
|
||||
}
|
||||
errors
|
||||
}
|
||||
|
||||
/// In theory `apply_concrete_opaque_types` could introduce new uses of opaque types.
|
||||
/// In theory `apply_hidden_types` could introduce new uses of opaque types.
|
||||
/// We do not check these new uses so this could be unsound.
|
||||
///
|
||||
/// We detect any new uses and simply delay a bug if they occur. If this results in
|
||||
|
|
@ -682,13 +666,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
///
|
||||
/// (*) C1 and C2 were introduced in the comments on
|
||||
/// `register_member_constraints`. Read that comment for more context.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `def_id`, the `impl Trait` type
|
||||
/// - `args`, the args used to instantiate this opaque type
|
||||
/// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
|
||||
/// `opaque_defn.concrete_ty`
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn infer_opaque_definition_from_instantiation(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ use smallvec::SmallVec;
|
|||
use crate::consumers::BorrowckConsumer;
|
||||
use crate::nll::compute_closure_requirements_modulo_opaques;
|
||||
use crate::region_infer::opaque_types::{
|
||||
apply_computed_concrete_opaque_types, clone_and_resolve_opaque_types,
|
||||
compute_concrete_opaque_types, detect_opaque_types_added_while_handling_opaque_types,
|
||||
apply_hidden_types, clone_and_resolve_opaque_types, compute_hidden_types,
|
||||
detect_opaque_types_added_while_handling_opaque_types,
|
||||
};
|
||||
use crate::type_check::{Locations, constraint_conversion};
|
||||
use crate::{
|
||||
ClosureRegionRequirements, CollectRegionConstraintsResult, ConcreteOpaqueTypes,
|
||||
ClosureRegionRequirements, CollectRegionConstraintsResult, HiddenTypes,
|
||||
PropagatedBorrowCheckResults, borrowck_check_region_constraints,
|
||||
borrowck_collect_region_constraints,
|
||||
};
|
||||
|
|
@ -27,7 +27,7 @@ use crate::{
|
|||
pub(super) struct BorrowCheckRootCtxt<'tcx> {
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
root_def_id: LocalDefId,
|
||||
concrete_opaque_types: ConcreteOpaqueTypes<'tcx>,
|
||||
hidden_types: HiddenTypes<'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.
|
||||
|
|
@ -49,7 +49,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
|
|||
BorrowCheckRootCtxt {
|
||||
tcx,
|
||||
root_def_id,
|
||||
concrete_opaque_types: Default::default(),
|
||||
hidden_types: Default::default(),
|
||||
collect_region_constraints_results: Default::default(),
|
||||
propagated_borrowck_results: Default::default(),
|
||||
tainted_by_errors: None,
|
||||
|
|
@ -72,11 +72,11 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
|
|||
&self.propagated_borrowck_results[&nested_body_def_id].used_mut_upvars
|
||||
}
|
||||
|
||||
pub(super) fn finalize(self) -> Result<&'tcx ConcreteOpaqueTypes<'tcx>, ErrorGuaranteed> {
|
||||
pub(super) fn finalize(self) -> Result<&'tcx HiddenTypes<'tcx>, ErrorGuaranteed> {
|
||||
if let Some(guar) = self.tainted_by_errors {
|
||||
Err(guar)
|
||||
} else {
|
||||
Ok(self.tcx.arena.alloc(self.concrete_opaque_types))
|
||||
Ok(self.tcx.arena.alloc(self.hidden_types))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,12 +88,12 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
|
|||
&input.universal_region_relations,
|
||||
&mut input.constraints,
|
||||
);
|
||||
input.deferred_opaque_type_errors = compute_concrete_opaque_types(
|
||||
input.deferred_opaque_type_errors = compute_hidden_types(
|
||||
&input.infcx,
|
||||
&input.universal_region_relations,
|
||||
&input.constraints,
|
||||
Rc::clone(&input.location_map),
|
||||
&mut self.concrete_opaque_types,
|
||||
&mut self.hidden_types,
|
||||
&opaque_types,
|
||||
);
|
||||
per_body_info.push((num_entries, opaque_types));
|
||||
|
|
@ -103,14 +103,14 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
|
|||
self.collect_region_constraints_results.values_mut().zip(per_body_info)
|
||||
{
|
||||
if input.deferred_opaque_type_errors.is_empty() {
|
||||
input.deferred_opaque_type_errors = apply_computed_concrete_opaque_types(
|
||||
input.deferred_opaque_type_errors = apply_hidden_types(
|
||||
&input.infcx,
|
||||
&input.body_owned,
|
||||
&input.universal_region_relations.universal_regions,
|
||||
&input.region_bound_pairs,
|
||||
&input.known_type_outlives_obligations,
|
||||
&mut input.constraints,
|
||||
&mut self.concrete_opaque_types,
|
||||
&mut self.hidden_types,
|
||||
&opaque_types,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
|
||||
// HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
|
||||
// `async-std` (and `pub async fn` in general).
|
||||
// Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
|
||||
// Since rustdoc doesn't care about the hidden type behind `impl Trait`, just don't look at it!
|
||||
// See https://github.com/rust-lang/rust/issues/75100
|
||||
if tcx.sess.opts.actually_rustdoc {
|
||||
return;
|
||||
|
|
@ -252,7 +252,7 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Check that the concrete type behind `impl Trait` actually implements `Trait`.
|
||||
/// Check that the hidden type behind `impl Trait` actually implements `Trait`.
|
||||
///
|
||||
/// This is mostly checked at the places that specify the opaque type, but we
|
||||
/// check those cases in the `param_env` of that function, which may have
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
|
|||
let tables = tcx.typeck(item_def_id);
|
||||
if let Some(guar) = tables.tainted_by_errors {
|
||||
self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
|
||||
} else if let Some(&hidden_type) = tables.concrete_opaque_types.get(&self.def_id) {
|
||||
} else if let Some(&hidden_type) = tables.hidden_types.get(&self.def_id) {
|
||||
self.insert_found(hidden_type);
|
||||
} else {
|
||||
self.non_defining_use_in_defining_scope(item_def_id);
|
||||
|
|
@ -185,8 +185,8 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
|
|||
}
|
||||
DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(item_def_id) {
|
||||
Err(guar) => self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)),
|
||||
Ok(concrete_opaque_types) => {
|
||||
if let Some(&hidden_type) = concrete_opaque_types.0.get(&self.def_id) {
|
||||
Ok(hidden_types) => {
|
||||
if let Some(&hidden_type) = hidden_types.0.get(&self.def_id) {
|
||||
debug!(?hidden_type, "found constraint");
|
||||
self.insert_found(hidden_type);
|
||||
} else if let Err(guar) = tcx
|
||||
|
|
@ -247,7 +247,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
|
|||
let tables = tcx.typeck(owner_def_id);
|
||||
if let Some(guar) = tables.tainted_by_errors {
|
||||
Ty::new_error(tcx, guar)
|
||||
} else if let Some(hidden_ty) = tables.concrete_opaque_types.get(&def_id) {
|
||||
} else if let Some(hidden_ty) = tables.hidden_types.get(&def_id) {
|
||||
hidden_ty.ty
|
||||
} else {
|
||||
assert!(!tcx.next_trait_solver_globally());
|
||||
|
|
@ -261,8 +261,8 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
|
|||
}
|
||||
}
|
||||
DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) {
|
||||
Ok(concrete_opaque_types) => {
|
||||
if let Some(hidden_ty) = concrete_opaque_types.0.get(&def_id) {
|
||||
Ok(hidden_types) => {
|
||||
if let Some(hidden_ty) = hidden_types.0.get(&def_id) {
|
||||
hidden_ty.ty
|
||||
} else {
|
||||
let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity();
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use crate::FnCtxt;
|
|||
|
||||
impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
/// This takes all the opaque type uses during HIR typeck. It first computes
|
||||
/// the concrete hidden type by iterating over all defining uses.
|
||||
/// the hidden type by iterating over all defining uses.
|
||||
///
|
||||
/// A use during HIR typeck is defining if all non-lifetime arguments are
|
||||
/// unique generic parameters and the hidden type does not reference any
|
||||
|
|
@ -35,8 +35,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
}
|
||||
debug!(?opaque_types);
|
||||
|
||||
self.compute_concrete_opaque_types(&opaque_types);
|
||||
self.apply_computed_concrete_opaque_types(&opaque_types);
|
||||
self.compute_hidden_types(&opaque_types);
|
||||
self.apply_hidden_types(&opaque_types);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ impl<'tcx> UsageKind<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
fn compute_concrete_opaque_types(
|
||||
fn compute_hidden_types(
|
||||
&mut self,
|
||||
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
|
||||
) {
|
||||
|
|
@ -142,7 +142,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.concrete_opaque_types
|
||||
.hidden_types
|
||||
.insert(def_id, OpaqueHiddenType::new_error(tcx, guar));
|
||||
self.set_tainted_by_errors(guar);
|
||||
}
|
||||
|
|
@ -161,7 +161,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
) {
|
||||
match err {
|
||||
NonDefiningUseReason::Tainted(guar) => {
|
||||
self.typeck_results.borrow_mut().concrete_opaque_types.insert(
|
||||
self.typeck_results.borrow_mut().hidden_types.insert(
|
||||
opaque_type_key.def_id,
|
||||
OpaqueHiddenType::new_error(self.tcx, guar),
|
||||
);
|
||||
|
|
@ -197,20 +197,19 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
|||
let prev = self
|
||||
.typeck_results
|
||||
.borrow_mut()
|
||||
.concrete_opaque_types
|
||||
.hidden_types
|
||||
.insert(opaque_type_key.def_id, hidden_type);
|
||||
assert!(prev.is_none());
|
||||
UsageKind::HasDefiningUse
|
||||
}
|
||||
|
||||
fn apply_computed_concrete_opaque_types(
|
||||
fn apply_hidden_types(
|
||||
&mut self,
|
||||
opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
|
||||
) {
|
||||
let tcx = self.tcx;
|
||||
for &(key, hidden_type) in opaque_types {
|
||||
let expected =
|
||||
*self.typeck_results.borrow_mut().concrete_opaque_types.get(&key.def_id).unwrap();
|
||||
let expected = *self.typeck_results.borrow_mut().hidden_types.get(&key.def_id).unwrap();
|
||||
|
||||
let expected = EarlyBinder::bind(expected.ty).instantiate(tcx, key.args);
|
||||
self.demand_eqtype(hidden_type.span, expected, hidden_type.ty);
|
||||
|
|
|
|||
|
|
@ -550,13 +550,12 @@ 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.concrete_opaque_types.values() {
|
||||
for hidden_ty in fcx_typeck_results.hidden_types.values() {
|
||||
assert!(!hidden_ty.has_infer());
|
||||
}
|
||||
|
||||
assert_eq!(self.typeck_results.concrete_opaque_types.len(), 0);
|
||||
self.typeck_results.concrete_opaque_types =
|
||||
mem::take(&mut fcx_typeck_results.concrete_opaque_types);
|
||||
assert_eq!(self.typeck_results.hidden_types.len(), 0);
|
||||
self.typeck_results.hidden_types = mem::take(&mut fcx_typeck_results.hidden_types);
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
|
@ -588,7 +587,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
hidden_type.span,
|
||||
DefiningScopeKind::HirTypeck,
|
||||
) {
|
||||
self.typeck_results.concrete_opaque_types.insert(
|
||||
self.typeck_results.hidden_types.insert(
|
||||
opaque_type_key.def_id,
|
||||
ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)),
|
||||
);
|
||||
|
|
@ -600,16 +599,11 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
DefiningScopeKind::HirTypeck,
|
||||
);
|
||||
|
||||
if let Some(prev) = self
|
||||
.typeck_results
|
||||
.concrete_opaque_types
|
||||
.insert(opaque_type_key.def_id, hidden_type)
|
||||
if let Some(prev) =
|
||||
self.typeck_results.hidden_types.insert(opaque_type_key.def_id, hidden_type)
|
||||
{
|
||||
let entry = &mut self
|
||||
.typeck_results
|
||||
.concrete_opaque_types
|
||||
.get_mut(&opaque_type_key.def_id)
|
||||
.unwrap();
|
||||
let entry =
|
||||
&mut 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);
|
||||
|
|
@ -628,7 +622,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
|
||||
let recursive_opaques: Vec<_> = self
|
||||
.typeck_results
|
||||
.concrete_opaque_types
|
||||
.hidden_types
|
||||
.iter()
|
||||
.filter(|&(&def_id, hidden_ty)| {
|
||||
hidden_ty
|
||||
|
|
@ -636,7 +630,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
.visit_with(&mut HasRecursiveOpaque {
|
||||
def_id,
|
||||
seen: Default::default(),
|
||||
opaques: &self.typeck_results.concrete_opaque_types,
|
||||
opaques: &self.typeck_results.hidden_types,
|
||||
tcx,
|
||||
})
|
||||
.is_break()
|
||||
|
|
@ -651,7 +645,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
.with_code(E0720)
|
||||
.emit();
|
||||
self.typeck_results
|
||||
.concrete_opaque_types
|
||||
.hidden_types
|
||||
.insert(def_id, OpaqueHiddenType { span, ty: Ty::new_error(tcx, guar) });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ macro_rules! arena_types {
|
|||
rustc_middle::mir::Body<'tcx>
|
||||
>,
|
||||
[decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>,
|
||||
[decode] borrowck_result: rustc_middle::mir::ConcreteOpaqueTypes<'tcx>,
|
||||
[decode] borrowck_result: rustc_middle::mir::HiddenTypes<'tcx>,
|
||||
[] resolver: rustc_data_structures::steal::Steal<(
|
||||
rustc_middle::ty::ResolverAstLowering,
|
||||
std::sync::Arc<rustc_ast::Crate>,
|
||||
|
|
|
|||
|
|
@ -84,11 +84,10 @@ impl Debug for CoroutineLayout<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// All the opaque types that are restricted to concrete types
|
||||
/// by this function. Unlike the value in `TypeckResults`, this has
|
||||
/// unerased regions.
|
||||
/// 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 ConcreteOpaqueTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>);
|
||||
pub struct HiddenTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>);
|
||||
|
||||
/// The result of the `mir_const_qualif` query.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1244,7 +1244,7 @@ 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::ConcreteOpaqueTypes<'tcx>, ErrorGuaranteed> {
|
||||
query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::HiddenTypes<'tcx>, ErrorGuaranteed> {
|
||||
desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
|
||||
pub hidden_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
|
||||
|
||||
/// Tracks the minimum captures required for a closure;
|
||||
/// see `MinCaptureInformationMap` for more details.
|
||||
|
|
@ -250,7 +250,7 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
coercion_casts: Default::default(),
|
||||
used_trait_imports: Default::default(),
|
||||
tainted_by_errors: None,
|
||||
concrete_opaque_types: Default::default(),
|
||||
hidden_types: Default::default(),
|
||||
closure_min_captures: Default::default(),
|
||||
closure_fake_reads: Default::default(),
|
||||
rvalue_scopes: Default::default(),
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> {
|
|||
impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
||||
/// Type inference occasionally gives us opaque types in places where corresponding patterns
|
||||
/// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited
|
||||
/// types, we use the corresponding concrete type if possible.
|
||||
/// types, we use the corresponding hidden type if possible.
|
||||
// FIXME(#132279): This will be unnecessary once we have a TypingMode which supports revealing
|
||||
// opaque types defined in a body.
|
||||
#[inline]
|
||||
|
|
@ -146,7 +146,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
/// know it.
|
||||
fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> {
|
||||
self.typeck_results
|
||||
.concrete_opaque_types
|
||||
.hidden_types
|
||||
.get(&key.def_id)
|
||||
.map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2359,7 +2359,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
if self.infcx.can_define_opaque_ty(def_id) {
|
||||
unreachable!()
|
||||
} else {
|
||||
// We can resolve the `impl Trait` to its concrete type,
|
||||
// We can resolve the opaque type to its hidden type,
|
||||
// which enforces a DAG between the functions requiring
|
||||
// the auto trait bounds in question.
|
||||
match self.tcx().type_of_opaque(def_id) {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ pub enum TypingMode<I: Interner> {
|
|||
/// the old solver as well.
|
||||
PostBorrowckAnalysis { defined_opaque_types: I::LocalDefIds },
|
||||
/// After analysis, mostly during codegen and MIR optimizations, we're able to
|
||||
/// reveal all opaque types. As the concrete type should *never* be observable
|
||||
/// reveal all opaque types. As the hidden type should *never* be observable
|
||||
/// directly by the user, this should not be used by checks which may expose
|
||||
/// such details to the user.
|
||||
///
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue