Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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);
Expand Down
116 changes: 58 additions & 58 deletions compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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>> {
Expand All @@ -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"),
}
Expand Down Expand Up @@ -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>>,
) {
Expand Down Expand Up @@ -310,22 +309,21 @@ 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
// the hidden type becomes the opaque type itself. In this case, this was an opaque
// 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
{
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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()
Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -677,23 +680,20 @@ 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,
instantiated_ty.span,
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)
}
}
12 changes: 7 additions & 5 deletions compiler/rustc_borrowck/src/root_cx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,16 @@ 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
/// items.
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.
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,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 {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand All @@ -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)
}
Expand Down Expand Up @@ -419,7 +419,7 @@ pub(super) fn type_of_opaque_hir_typeck(
DefiningScopeKind::HirTypeck,
)
}
})
}
}

fn infer_placeholder_type<'tcx>(
Expand Down
Loading
Loading