Skip to content

Commit

Permalink
Auto merge of rust-lang#96367 - Mark-Simulacrum:beta-next, r=Mark-Sim…
Browse files Browse the repository at this point in the history
…ulacrum

[beta] backports rollup

*  Remove NodeIdHashingMode. rust-lang#95656
*  Check that all hidden types are the same and then deduplicate them. rust-lang#95731

r? `@Mark-Simulacrum`
  • Loading branch information
bors committed Apr 25, 2022
2 parents 2431a97 + d76101d commit 69a6d12
Show file tree
Hide file tree
Showing 23 changed files with 196 additions and 454 deletions.
142 changes: 80 additions & 62 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,75 +55,93 @@ impl<'tcx> RegionInferenceContext<'tcx> {
infcx: &InferCtxt<'_, 'tcx>,
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
) -> VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> {
opaque_ty_decls
.into_iter()
.map(|(opaque_type_key, (concrete_type, origin))| {
let substs = opaque_type_key.substs;
debug!(?concrete_type, ?substs);
let mut result: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> = VecMap::new();
for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
let substs = opaque_type_key.substs;
debug!(?concrete_type, ?substs);

let mut subst_regions = vec![self.universal_regions.fr_static];
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
if let ty::RePlaceholder(..) = region.kind() {
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
return region;
let mut subst_regions = vec![self.universal_regions.fr_static];
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
if let ty::RePlaceholder(..) = region.kind() {
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
return region;
}
let vid = self.to_region_vid(region);
trace!(?vid);
let scc = self.constraint_sccs.scc(vid);
trace!(?scc);
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
}) {
Some(region) => {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
region
}
let vid = self.to_region_vid(region);
trace!(?vid);
let scc = self.constraint_sccs.scc(vid);
trace!(?scc);
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
}) {
Some(region) => {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
region
}
None => {
subst_regions.push(vid);
infcx.tcx.sess.delay_span_bug(
concrete_type.span,
"opaque type with non-universal region substs",
);
infcx.tcx.lifetimes.re_static
}
None => {
subst_regions.push(vid);
infcx.tcx.sess.delay_span_bug(
concrete_type.span,
"opaque type with non-universal region substs",
);
infcx.tcx.lifetimes.re_static
}
});
}
});

subst_regions.sort();
subst_regions.dedup();
subst_regions.sort();
subst_regions.dedup();

let universal_concrete_type =
infcx.tcx.fold_regions(concrete_type, &mut false, |region, _| match *region {
ty::ReVar(vid) => subst_regions
.iter()
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)
.unwrap_or(infcx.tcx.lifetimes.re_root_empty),
_ => region,
});
let universal_concrete_type =
infcx.tcx.fold_regions(concrete_type, &mut false, |region, _| match *region {
ty::ReVar(vid) => subst_regions
.iter()
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)
.unwrap_or(infcx.tcx.lifetimes.re_root_empty),
_ => region,
});

debug!(?universal_concrete_type, ?universal_substs);
debug!(?universal_concrete_type, ?universal_substs);

let opaque_type_key =
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
opaque_type_key,
universal_concrete_type,
);
let ty = if check_opaque_type_parameter_valid(
infcx.tcx,
opaque_type_key,
origin,
concrete_type.span,
) {
remapped_type
} else {
infcx.tcx.ty_error()
};
(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span })
})
.collect()
let opaque_type_key =
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
opaque_type_key,
universal_concrete_type,
);
let ty = if check_opaque_type_parameter_valid(
infcx.tcx,
opaque_type_key,
origin,
concrete_type.span,
) {
remapped_type
} else {
infcx.tcx.ty_error()
};
// 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) = result.get_mut(&opaque_type_key) {
if prev.ty != ty {
let mut err = infcx.tcx.sess.struct_span_err(
concrete_type.span,
&format!("hidden type `{}` differed from previous `{}`", ty, prev.ty),
);
err.span_note(prev.span, "previous hidden type bound here");
err.emit();
prev.ty = infcx.tcx.ty_error();
}
// 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(concrete_type.span);
} else {
result.insert(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span });
}
}
result
}

/// Map the regions in the type to named regions. This is similar to what
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::cell::RefCell;
use rustc_data_structures::{
fingerprint::Fingerprint,
fx::FxHashMap,
stable_hasher::{HashStable, NodeIdHashingMode, StableHasher},
stable_hasher::{HashStable, StableHasher},
};
use rustc_middle::{
bug,
Expand Down Expand Up @@ -94,11 +94,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
pub fn generate_unique_id_string(self, tcx: TyCtxt<'tcx>) -> String {
let mut hasher = StableHasher::new();
let mut hcx = tcx.create_stable_hashing_context();
hcx.while_hashing_spans(false, |hcx| {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
self.hash_stable(hcx, &mut hasher);
});
});
hcx.while_hashing_spans(false, |hcx| self.hash_stable(hcx, &mut hasher));
hasher.finish::<Fingerprint>().to_hex()
}

Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, ExistentialProjection, GeneratorSubsts, ParamEnv, Ty, TyCtxt};
use rustc_query_system::ich::NodeIdHashingMode;
use rustc_target::abi::{Integer, TagEncoding, Variants};
use smallvec::SmallVec;

Expand Down Expand Up @@ -704,11 +703,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
// but we get a deterministic, virtually unique value for the constant.
let hcx = &mut tcx.create_stable_hashing_context();
let mut hasher = StableHasher::new();
hcx.while_hashing_spans(false, |hcx| {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
ct.val().hash_stable(hcx, &mut hasher);
});
});
hcx.while_hashing_spans(false, |hcx| ct.val().hash_stable(hcx, &mut hasher));
// Let's only emit 64 bits of the hash value. That should be plenty for
// avoiding collisions and will make the emitted type names shorter.
let hash: u64 = hasher.finish();
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_data_structures/src/stable_hasher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,12 +612,6 @@ fn stable_hash_reduce<HCX, I, C, F>(
}
}

#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
pub enum NodeIdHashingMode {
Ignore,
HashDefPath,
}

/// Controls what data we do or not not hash.
/// Whenever a `HashStable` implementation caches its
/// result, it needs to include `HashingControls` as part
Expand All @@ -628,5 +622,4 @@ pub enum NodeIdHashingMode {
#[derive(Clone, Hash, Eq, PartialEq, Debug)]
pub struct HashingControls {
pub hash_spans: bool,
pub node_id_hashing_mode: NodeIdHashingMode,
}
22 changes: 11 additions & 11 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1264,7 +1264,7 @@ pub struct BodyId {
///
/// All bodies have an **owner**, which can be accessed via the HIR
/// map using `body_owner_def_id()`.
#[derive(Debug)]
#[derive(Debug, HashStable_Generic)]
pub struct Body<'hir> {
pub params: &'hir [Param<'hir>],
pub value: Expr<'hir>,
Expand Down Expand Up @@ -2024,7 +2024,7 @@ pub struct FnSig<'hir> {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
pub struct TraitItemId {
pub def_id: LocalDefId,
}
Expand All @@ -2041,7 +2041,7 @@ impl TraitItemId {
/// possibly including a default implementation. A trait item is
/// either required (meaning it doesn't have an implementation, just a
/// signature) or provided (meaning it has a default implementation).
#[derive(Debug)]
#[derive(Debug, HashStable_Generic)]
pub struct TraitItem<'hir> {
pub ident: Ident,
pub def_id: LocalDefId,
Expand Down Expand Up @@ -2087,7 +2087,7 @@ pub enum TraitItemKind<'hir> {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
pub struct ImplItemId {
pub def_id: LocalDefId,
}
Expand All @@ -2101,7 +2101,7 @@ impl ImplItemId {
}

/// Represents anything within an `impl` block.
#[derive(Debug)]
#[derive(Debug, HashStable_Generic)]
pub struct ImplItem<'hir> {
pub ident: Ident,
pub def_id: LocalDefId,
Expand Down Expand Up @@ -2602,7 +2602,7 @@ pub struct PolyTraitRef<'hir> {

pub type Visibility<'hir> = Spanned<VisibilityKind<'hir>>;

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub enum VisibilityKind<'hir> {
Public,
Crate(CrateSugar),
Expand Down Expand Up @@ -2678,7 +2678,7 @@ impl<'hir> VariantData<'hir> {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, Hash)]
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, Hash, HashStable_Generic)]
pub struct ItemId {
pub def_id: LocalDefId,
}
Expand All @@ -2694,7 +2694,7 @@ impl ItemId {
/// An item
///
/// The name might be a dummy name in case of anonymous items
#[derive(Debug)]
#[derive(Debug, HashStable_Generic)]
pub struct Item<'hir> {
pub ident: Ident,
pub def_id: LocalDefId,
Expand Down Expand Up @@ -2925,7 +2925,7 @@ pub enum AssocItemKind {
// The bodies for items are stored "out of line", in a separate
// hashmap in the `Crate`. Here we just record the hir-id of the item
// so it can fetched later.
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
pub struct ForeignItemId {
pub def_id: LocalDefId,
}
Expand All @@ -2951,7 +2951,7 @@ pub struct ForeignItemRef {
pub span: Span,
}

#[derive(Debug)]
#[derive(Debug, HashStable_Generic)]
pub struct ForeignItem<'hir> {
pub ident: Ident,
pub kind: ForeignItemKind<'hir>,
Expand Down Expand Up @@ -2993,7 +2993,7 @@ pub struct Upvar {
// The TraitCandidate's import_ids is empty if the trait is defined in the same module, and
// has length > 0 if the trait is found through an chain of imports, starting with the
// import/use statement in the scope where the trait is used.
#[derive(Encodable, Decodable, Clone, Debug)]
#[derive(Encodable, Decodable, Clone, Debug, HashStable_Generic)]
pub struct TraitCandidate {
pub def_id: DefId,
pub import_ids: SmallVec<[LocalDefId; 1]>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::fmt;
/// incremental compilation where we have to persist things through changes to
/// the code base.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Encodable, Decodable)]
#[derive(Encodable, Decodable, HashStable_Generic)]
#[rustc_pass_by_value]
pub struct HirId {
pub owner: LocalDefId,
Expand Down
Loading

0 comments on commit 69a6d12

Please sign in to comment.