Remove global next_disambiguator state and handle it with a DisambiguatorState type
This commit is contained in:
parent
2ac60bc089
commit
e561ec0e03
24 changed files with 190 additions and 93 deletions
|
|
@ -509,7 +509,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
self.tcx.hir_def_key(self.local_def_id(node_id)),
|
||||
);
|
||||
|
||||
let def_id = self.tcx.at(span).create_def(parent, name, def_kind).def_id();
|
||||
let def_id = self
|
||||
.tcx
|
||||
.at(span)
|
||||
.create_def(parent, name, def_kind, None, &mut self.resolver.disambiguator)
|
||||
.def_id();
|
||||
|
||||
debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
|
||||
self.resolver.node_id_to_def_id.insert(node_id, def_id);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::definitions::DisambiguatorState;
|
||||
use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
|
|
@ -42,7 +44,7 @@ pub macro throw_machine_stop_str($($tt:tt)*) {{
|
|||
pub struct DummyMachine;
|
||||
|
||||
impl HasStaticRootDefId for DummyMachine {
|
||||
fn static_def_id(&self) -> Option<rustc_hir::def_id::LocalDefId> {
|
||||
fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use rustc_abi::{Align, Size};
|
|||
use rustc_ast::Mutability;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::definitions::DisambiguatorState;
|
||||
use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem};
|
||||
use rustc_middle::mir::AssertMessage;
|
||||
use rustc_middle::mir::interpret::ReportedErrorInfo;
|
||||
|
|
@ -63,7 +64,7 @@ pub struct CompileTimeMachine<'tcx> {
|
|||
/// If `Some`, we are evaluating the initializer of the static with the given `LocalDefId`,
|
||||
/// storing the result in the given `AllocId`.
|
||||
/// Used to prevent reads from a static's base allocation, as that may allow for self-initialization loops.
|
||||
pub(crate) static_root_ids: Option<(AllocId, LocalDefId)>,
|
||||
pub(crate) static_root_ids: Option<(AllocId, LocalDefId, DisambiguatorState)>,
|
||||
|
||||
/// A cache of "data range" computations for unions (i.e., the offsets of non-padding bytes).
|
||||
union_data_ranges: FxHashMap<Ty<'tcx>, RangeSet>,
|
||||
|
|
@ -706,7 +707,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
|||
|
||||
fn before_alloc_read(ecx: &InterpCx<'tcx, Self>, alloc_id: AllocId) -> InterpResult<'tcx> {
|
||||
// Check if this is the currently evaluated static.
|
||||
if Some(alloc_id) == ecx.machine.static_root_ids.map(|(id, _)| id) {
|
||||
if Some(alloc_id) == ecx.machine.static_root_ids.as_ref().map(|(id, ..)| *id) {
|
||||
return Err(ConstEvalErrKind::RecursiveStatic).into();
|
||||
}
|
||||
// If this is another static, make sure we fire off the query to detect cycles.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use hir::def::DefKind;
|
|||
use rustc_ast::Mutability;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::definitions::DisambiguatorState;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::mir::interpret::{ConstAllocation, CtfeProvenance, InterpResult};
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
|
|
@ -46,12 +47,13 @@ pub trait CompileTimeMachine<'tcx, T> = Machine<
|
|||
pub trait HasStaticRootDefId {
|
||||
/// Returns the `DefId` of the static item that is currently being evaluated.
|
||||
/// Used for interning to be able to handle nested allocations.
|
||||
fn static_def_id(&self) -> Option<LocalDefId>;
|
||||
fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)>;
|
||||
}
|
||||
|
||||
impl HasStaticRootDefId for const_eval::CompileTimeMachine<'_> {
|
||||
fn static_def_id(&self) -> Option<LocalDefId> {
|
||||
Some(self.static_root_ids?.1)
|
||||
fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)> {
|
||||
let (_, static_id, d) = self.static_root_ids.as_mut()?;
|
||||
Some((*static_id, d))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,8 +89,8 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
|
|||
}
|
||||
// link the alloc id to the actual allocation
|
||||
let alloc = ecx.tcx.mk_const_alloc(alloc);
|
||||
if let Some(static_id) = ecx.machine.static_def_id() {
|
||||
intern_as_new_static(ecx.tcx, static_id, alloc_id, alloc);
|
||||
if let Some((static_id, disambiguator)) = ecx.machine.static_parent_and_disambiguator() {
|
||||
intern_as_new_static(ecx.tcx, static_id, alloc_id, alloc, disambiguator);
|
||||
} else {
|
||||
ecx.tcx.set_alloc_id_memory(alloc_id, alloc);
|
||||
}
|
||||
|
|
@ -102,11 +104,14 @@ fn intern_as_new_static<'tcx>(
|
|||
static_id: LocalDefId,
|
||||
alloc_id: AllocId,
|
||||
alloc: ConstAllocation<'tcx>,
|
||||
disambiguator: &mut DisambiguatorState,
|
||||
) {
|
||||
let feed = tcx.create_def(
|
||||
static_id,
|
||||
Some(sym::nested),
|
||||
DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true },
|
||||
None,
|
||||
disambiguator,
|
||||
);
|
||||
tcx.set_nested_alloc_id_static(alloc_id, feed.def_id());
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::definitions::DisambiguatorState;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{AllocInit, Allocation, InterpResult, Pointer};
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
|
|
@ -40,8 +41,8 @@ pub(crate) fn create_static_alloc<'tcx>(
|
|||
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let alloc = Allocation::try_new(layout.size, layout.align.abi, AllocInit::Uninit)?;
|
||||
let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into());
|
||||
assert_eq!(ecx.machine.static_root_ids, None);
|
||||
ecx.machine.static_root_ids = Some((alloc_id, static_def_id));
|
||||
assert!(ecx.machine.static_root_ids.is_none());
|
||||
ecx.machine.static_root_ids = Some((alloc_id, static_def_id, DisambiguatorState::new()));
|
||||
assert!(ecx.memory.alloc_map.insert(alloc_id, (MemoryKind::Stack, alloc)).is_none());
|
||||
interp_ok(ecx.ptr_to_mplace(Pointer::from(alloc_id).into(), layout))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,14 +269,9 @@ impl DefKind {
|
|||
| DefKind::TyParam
|
||||
| DefKind::ExternCrate => DefPathData::TypeNs(name.unwrap()),
|
||||
|
||||
// An associated type name will be missing for an RPITIT.
|
||||
DefKind::AssocTy => {
|
||||
if let Some(name) = name {
|
||||
DefPathData::TypeNs(name)
|
||||
} else {
|
||||
DefPathData::AnonAssocTy
|
||||
}
|
||||
}
|
||||
// An associated type name will be missing for an RPITIT (DefPathData::AnonAssocTy),
|
||||
// but those provide their own DefPathData.
|
||||
DefKind::AssocTy => DefPathData::TypeNs(name.unwrap()),
|
||||
|
||||
// It's not exactly an anon const, but wrt DefPathData, there
|
||||
// is no difference.
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ impl DefPathTable {
|
|||
//
|
||||
// See the documentation for DefPathHash for more information.
|
||||
panic!(
|
||||
"found DefPathHash collision between {def_path1:?} and {def_path2:?}. \
|
||||
"found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
|
||||
Compilation cannot continue."
|
||||
);
|
||||
}
|
||||
|
|
@ -97,13 +97,31 @@ impl DefPathTable {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DisambiguatorState {
|
||||
next: UnordMap<(LocalDefId, DefPathData), u32>,
|
||||
}
|
||||
|
||||
impl DisambiguatorState {
|
||||
pub fn new() -> Self {
|
||||
Self { next: Default::default() }
|
||||
}
|
||||
|
||||
/// Creates a `DisambiguatorState` where the next allocated `(LocalDefId, DefPathData)` pair
|
||||
/// will have `index` as the disambiguator.
|
||||
pub fn with(def_id: LocalDefId, data: DefPathData, index: u32) -> Self {
|
||||
let mut this = Self::new();
|
||||
this.next.insert((def_id, data), index);
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
/// The definition table containing node definitions.
|
||||
/// It holds the `DefPathTable` for `LocalDefId`s/`DefPath`s.
|
||||
/// It also stores mappings to convert `LocalDefId`s to/from `HirId`s.
|
||||
#[derive(Debug)]
|
||||
pub struct Definitions {
|
||||
table: DefPathTable,
|
||||
next_disambiguator: UnordMap<(LocalDefId, DefPathData), u32>,
|
||||
}
|
||||
|
||||
/// A unique identifier that we can use to lookup a definition
|
||||
|
|
@ -173,7 +191,11 @@ impl DisambiguatedDefPathData {
|
|||
}
|
||||
}
|
||||
DefPathDataName::Anon { namespace } => {
|
||||
write!(writer, "{{{}#{}}}", namespace, self.disambiguator)
|
||||
if let DefPathData::AnonAssocTy(method) = self.data {
|
||||
write!(writer, "{}::{{{}#{}}}", method, namespace, self.disambiguator)
|
||||
} else {
|
||||
write!(writer, "{{{}#{}}}", namespace, self.disambiguator)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -288,7 +310,7 @@ pub enum DefPathData {
|
|||
/// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name.
|
||||
OpaqueTy,
|
||||
/// An anonymous associated type from an RPITIT.
|
||||
AnonAssocTy,
|
||||
AnonAssocTy(Symbol),
|
||||
/// A synthetic body for a coroutine's by-move body.
|
||||
SyntheticCoroutineBody,
|
||||
}
|
||||
|
|
@ -342,11 +364,20 @@ impl Definitions {
|
|||
let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) };
|
||||
assert_eq!(root.local_def_index, CRATE_DEF_INDEX);
|
||||
|
||||
Definitions { table, next_disambiguator: Default::default() }
|
||||
Definitions { table }
|
||||
}
|
||||
|
||||
/// Adds a definition with a parent definition.
|
||||
pub fn create_def(&mut self, parent: LocalDefId, data: DefPathData) -> LocalDefId {
|
||||
/// Creates a definition with a parent definition.
|
||||
/// If there are multiple definitions with the same DefPathData and the same parent, use
|
||||
/// `disambiguator` to differentiate them. Distinct `DisambiguatorState` instances are not
|
||||
/// guaranteed to generate unique disambiguators and should instead ensure that the `parent`
|
||||
/// and `data` pair is distinct from other instances.
|
||||
pub fn create_def(
|
||||
&mut self,
|
||||
parent: LocalDefId,
|
||||
data: DefPathData,
|
||||
disambiguator: &mut DisambiguatorState,
|
||||
) -> LocalDefId {
|
||||
// We can't use `Debug` implementation for `LocalDefId` here, since it tries to acquire a
|
||||
// reference to `Definitions` and we're already holding a mutable reference.
|
||||
debug!(
|
||||
|
|
@ -354,12 +385,12 @@ impl Definitions {
|
|||
self.def_path(parent).to_string_no_crate_verbose(),
|
||||
);
|
||||
|
||||
// The root node must be created with `create_root_def()`.
|
||||
// The root node must be created in `new()`.
|
||||
assert!(data != DefPathData::CrateRoot);
|
||||
|
||||
// Find the next free disambiguator for this key.
|
||||
let disambiguator = {
|
||||
let next_disamb = self.next_disambiguator.entry((parent, data)).or_insert(0);
|
||||
let next_disamb = disambiguator.next.entry((parent, data)).or_insert(0);
|
||||
let disambiguator = *next_disamb;
|
||||
*next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow");
|
||||
disambiguator
|
||||
|
|
@ -411,7 +442,9 @@ impl DefPathData {
|
|||
pub fn get_opt_name(&self) -> Option<Symbol> {
|
||||
use self::DefPathData::*;
|
||||
match *self {
|
||||
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
|
||||
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name) => {
|
||||
Some(name)
|
||||
}
|
||||
|
||||
Impl
|
||||
| ForeignMod
|
||||
|
|
@ -422,7 +455,6 @@ impl DefPathData {
|
|||
| Ctor
|
||||
| AnonConst
|
||||
| OpaqueTy
|
||||
| AnonAssocTy
|
||||
| SyntheticCoroutineBody => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -443,7 +475,7 @@ impl DefPathData {
|
|||
Ctor => DefPathDataName::Anon { namespace: sym::constructor },
|
||||
AnonConst => DefPathDataName::Anon { namespace: sym::constant },
|
||||
OpaqueTy => DefPathDataName::Anon { namespace: sym::opaque },
|
||||
AnonAssocTy => DefPathDataName::Anon { namespace: sym::anon_assoc },
|
||||
AnonAssocTy(..) => DefPathDataName::Anon { namespace: sym::anon_assoc },
|
||||
SyntheticCoroutineBody => DefPathDataName::Anon { namespace: sym::synthetic },
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use rustc_ast::visit::walk_list;
|
|||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::definitions::DisambiguatorState;
|
||||
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
|
||||
use rustc_hir::{
|
||||
self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node,
|
||||
|
|
@ -63,6 +64,7 @@ impl ResolvedArg {
|
|||
struct BoundVarContext<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
rbv: &'a mut ResolveBoundVars,
|
||||
disambiguator: &'a mut DisambiguatorState,
|
||||
scope: ScopeRef<'a>,
|
||||
}
|
||||
|
||||
|
|
@ -245,8 +247,12 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||
#[instrument(level = "debug", skip(tcx))]
|
||||
fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBoundVars {
|
||||
let mut rbv = ResolveBoundVars::default();
|
||||
let mut visitor =
|
||||
BoundVarContext { tcx, rbv: &mut rbv, scope: &Scope::Root { opt_parent_item: None } };
|
||||
let mut visitor = BoundVarContext {
|
||||
tcx,
|
||||
rbv: &mut rbv,
|
||||
scope: &Scope::Root { opt_parent_item: None },
|
||||
disambiguator: &mut DisambiguatorState::new(),
|
||||
};
|
||||
match tcx.hir_owner_node(local_def_id) {
|
||||
hir::OwnerNode::Item(item) => visitor.visit_item(item),
|
||||
hir::OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
|
||||
|
|
@ -515,9 +521,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
|
||||
let capture_all_in_scope_lifetimes = opaque_captures_all_in_scope_lifetimes(opaque);
|
||||
if capture_all_in_scope_lifetimes {
|
||||
let tcx = self.tcx;
|
||||
let lifetime_ident = |def_id: LocalDefId| {
|
||||
let name = self.tcx.item_name(def_id.to_def_id());
|
||||
let span = self.tcx.def_span(def_id);
|
||||
let name = tcx.item_name(def_id.to_def_id());
|
||||
let span = tcx.def_span(def_id);
|
||||
Ident::new(name, span)
|
||||
};
|
||||
|
||||
|
|
@ -1091,8 +1098,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
where
|
||||
F: for<'b> FnOnce(&mut BoundVarContext<'b, 'tcx>),
|
||||
{
|
||||
let BoundVarContext { tcx, rbv, .. } = self;
|
||||
let mut this = BoundVarContext { tcx: *tcx, rbv, scope: &wrap_scope };
|
||||
let BoundVarContext { tcx, rbv, disambiguator, .. } = self;
|
||||
let mut this = BoundVarContext { tcx: *tcx, rbv, disambiguator, scope: &wrap_scope };
|
||||
let span = debug_span!("scope", scope = ?this.scope.debug_truncated());
|
||||
{
|
||||
let _enter = span.enter();
|
||||
|
|
@ -1446,7 +1453,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
|
||||
#[instrument(level = "trace", skip(self, opaque_capture_scopes), ret)]
|
||||
fn remap_opaque_captures(
|
||||
&self,
|
||||
&mut self,
|
||||
opaque_capture_scopes: &Vec<(LocalDefId, &RefCell<FxIndexMap<ResolvedArg, LocalDefId>>)>,
|
||||
mut lifetime: ResolvedArg,
|
||||
ident: Ident,
|
||||
|
|
@ -1462,8 +1469,13 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
for &(opaque_def_id, captures) in opaque_capture_scopes.iter().rev() {
|
||||
let mut captures = captures.borrow_mut();
|
||||
let remapped = *captures.entry(lifetime).or_insert_with(|| {
|
||||
let feed =
|
||||
self.tcx.create_def(opaque_def_id, Some(ident.name), DefKind::LifetimeParam);
|
||||
let feed = self.tcx.create_def(
|
||||
opaque_def_id,
|
||||
Some(ident.name),
|
||||
DefKind::LifetimeParam,
|
||||
None,
|
||||
&mut self.disambiguator,
|
||||
);
|
||||
feed.def_span(ident.span);
|
||||
feed.def_ident_span(Some(ident.span));
|
||||
feed.def_id()
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ use rustc_errors::{
|
|||
};
|
||||
use rustc_hir::def::{CtorKind, DefKind};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_hir::definitions::Definitions;
|
||||
use rustc_hir::definitions::{DefPathData, Definitions, DisambiguatorState};
|
||||
use rustc_hir::intravisit::VisitorExt;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{self as hir, Attribute, HirId, Node, TraitCandidate};
|
||||
|
|
@ -1957,8 +1957,10 @@ impl<'tcx> TyCtxtAt<'tcx> {
|
|||
parent: LocalDefId,
|
||||
name: Option<Symbol>,
|
||||
def_kind: DefKind,
|
||||
def_path_data: Option<DefPathData>,
|
||||
disambiguator: &mut DisambiguatorState,
|
||||
) -> TyCtxtFeed<'tcx, LocalDefId> {
|
||||
let feed = self.tcx.create_def(parent, name, def_kind);
|
||||
let feed = self.tcx.create_def(parent, name, def_kind, def_path_data, disambiguator);
|
||||
|
||||
feed.def_span(self.span);
|
||||
feed
|
||||
|
|
@ -1972,8 +1974,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
parent: LocalDefId,
|
||||
name: Option<Symbol>,
|
||||
def_kind: DefKind,
|
||||
def_path_data: Option<DefPathData>,
|
||||
disambiguator: &mut DisambiguatorState,
|
||||
) -> TyCtxtFeed<'tcx, LocalDefId> {
|
||||
let data = def_kind.def_path_data(name);
|
||||
let data = def_path_data.unwrap_or_else(|| def_kind.def_path_data(name));
|
||||
// The following call has the side effect of modifying the tables inside `definitions`.
|
||||
// These very tables are relied on by the incr. comp. engine to decode DepNodes and to
|
||||
// decode the on-disk cache.
|
||||
|
|
@ -1983,12 +1987,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
// - has been created by this call to `create_def`.
|
||||
// As a consequence, this LocalDefId is always re-created before it is needed by the incr.
|
||||
// comp. engine itself.
|
||||
//
|
||||
// This call also writes to the value of the `source_span` query.
|
||||
// This is fine because:
|
||||
// - that query is `eval_always` so we won't miss its result changing;
|
||||
// - this write will have happened before that query is called.
|
||||
let def_id = self.untracked.definitions.write().create_def(parent, data);
|
||||
let def_id = self.untracked.definitions.write().create_def(parent, data, disambiguator);
|
||||
|
||||
// This function modifies `self.definitions` using a side-effect.
|
||||
// We need to ensure that these side effects are re-run by the incr. comp. engine.
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ use rustc_errors::{Diag, ErrorGuaranteed};
|
|||
use rustc_hir::LangItem;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
|
||||
use rustc_hir::definitions::DisambiguatorState;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_macros::{
|
||||
Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
|
||||
|
|
@ -207,6 +208,8 @@ pub struct ResolverAstLowering {
|
|||
|
||||
pub node_id_to_def_id: NodeMap<LocalDefId>,
|
||||
|
||||
pub disambiguator: DisambiguatorState,
|
||||
|
||||
pub trait_map: NodeMap<Vec<hir::TraitCandidate>>,
|
||||
/// List functions and methods for which lifetime elision was successful.
|
||||
pub lifetime_elision_allowed: FxHashSet<ast::NodeId>,
|
||||
|
|
|
|||
|
|
@ -391,6 +391,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
let visible_parent_map = self.tcx().visible_parent_map(());
|
||||
let kind = self.tcx().def_kind(def_id);
|
||||
|
||||
if let DefPathData::AnonAssocTy(..) = key.disambiguated_data.data {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let get_local_name = |this: &Self, name, def_id, key: DefKey| {
|
||||
if let Some(visible_parent) = visible_parent_map.get(&def_id)
|
||||
&& let actual_parent = this.tcx().opt_parent(def_id)
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ use rustc_data_structures::unord::UnordMap;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::definitions::DisambiguatorState;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::hir::place::{Projection, ProjectionKind};
|
||||
use rustc_middle::mir::visit::MutVisitor;
|
||||
|
|
@ -213,8 +214,13 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
|
|||
let mut by_move_body = body.clone();
|
||||
MakeByMoveBody { tcx, field_remapping, by_move_coroutine_ty }.visit_body(&mut by_move_body);
|
||||
|
||||
// This will always be `{closure#1}`, since the original coroutine is `{closure#0}`.
|
||||
let body_def = tcx.create_def(parent_def_id, None, DefKind::SyntheticCoroutineBody);
|
||||
let body_def = tcx.create_def(
|
||||
parent_def_id,
|
||||
None,
|
||||
DefKind::SyntheticCoroutineBody,
|
||||
None,
|
||||
&mut DisambiguatorState::new(),
|
||||
);
|
||||
by_move_body.source =
|
||||
mir::MirSource::from_instance(InstanceKind::Item(body_def.def_id().to_def_id()));
|
||||
dump_mir(tcx, false, "built", &"after", &by_move_body, |_, _| Ok(()));
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ use rustc_hir::def::{
|
|||
self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS,
|
||||
};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap};
|
||||
use rustc_hir::definitions::DisambiguatorState;
|
||||
use rustc_hir::{PrimTy, TraitCandidate};
|
||||
use rustc_metadata::creader::{CStore, CrateLoader};
|
||||
use rustc_middle::metadata::ModChild;
|
||||
|
|
@ -1184,6 +1185,8 @@ pub struct Resolver<'ra, 'tcx> {
|
|||
|
||||
node_id_to_def_id: NodeMap<Feed<'tcx, LocalDefId>>,
|
||||
|
||||
disambiguator: DisambiguatorState,
|
||||
|
||||
/// Indices of unnamed struct or variant fields with unresolved attributes.
|
||||
placeholder_field_indices: FxHashMap<NodeId, usize>,
|
||||
/// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
|
||||
|
|
@ -1347,7 +1350,7 @@ impl<'tcx> Resolver<'_, 'tcx> {
|
|||
);
|
||||
|
||||
// FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()`
|
||||
let feed = self.tcx.create_def(parent, name, def_kind);
|
||||
let feed = self.tcx.create_def(parent, name, def_kind, None, &mut self.disambiguator);
|
||||
let def_id = feed.def_id();
|
||||
|
||||
// Create the definition.
|
||||
|
|
@ -1561,6 +1564,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
lint_buffer: LintBuffer::default(),
|
||||
next_node_id: CRATE_NODE_ID,
|
||||
node_id_to_def_id,
|
||||
disambiguator: DisambiguatorState::new(),
|
||||
placeholder_field_indices: Default::default(),
|
||||
invocation_parents,
|
||||
legacy_const_generic_args: Default::default(),
|
||||
|
|
@ -1690,6 +1694,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
.into_items()
|
||||
.map(|(k, f)| (k, f.key()))
|
||||
.collect(),
|
||||
disambiguator: self.disambiguator,
|
||||
trait_map: self.trait_map,
|
||||
lifetime_elision_allowed: self.lifetime_elision_allowed,
|
||||
lint_buffer: Steal::new(self.lint_buffer),
|
||||
|
|
|
|||
|
|
@ -722,7 +722,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
|
|||
| hir::definitions::DefPathData::GlobalAsm
|
||||
| hir::definitions::DefPathData::MacroNs(..)
|
||||
| hir::definitions::DefPathData::LifetimeNs(..)
|
||||
| hir::definitions::DefPathData::AnonAssocTy => {
|
||||
| hir::definitions::DefPathData::AnonAssocTy(..) => {
|
||||
bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -859,7 +859,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
|||
| DefPathData::Impl
|
||||
| DefPathData::MacroNs(_)
|
||||
| DefPathData::LifetimeNs(_)
|
||||
| DefPathData::AnonAssocTy => {
|
||||
| DefPathData::AnonAssocTy(..) => {
|
||||
bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data)
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
|
||||
use rustc_hir::definitions::{DefPathData, DisambiguatorState};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{self as hir, AmbigArg};
|
||||
use rustc_middle::query::Providers;
|
||||
|
|
@ -159,6 +160,22 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
|
|||
container: ty::AssocItemContainer::Impl,
|
||||
}
|
||||
}
|
||||
struct RPITVisitor {
|
||||
rpits: FxIndexSet<LocalDefId>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for RPITVisitor {
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
|
||||
if let hir::TyKind::OpaqueDef(opaq) = ty.kind
|
||||
&& self.rpits.insert(opaq.def_id)
|
||||
{
|
||||
for bound in opaq.bounds {
|
||||
intravisit::walk_param_bound(self, bound);
|
||||
}
|
||||
}
|
||||
intravisit::walk_ty(self, ty)
|
||||
}
|
||||
}
|
||||
|
||||
/// Given an `fn_def_id` of a trait or a trait implementation:
|
||||
///
|
||||
|
|
@ -177,23 +194,6 @@ fn associated_types_for_impl_traits_in_associated_fn(
|
|||
|
||||
match tcx.def_kind(parent_def_id) {
|
||||
DefKind::Trait => {
|
||||
struct RPITVisitor {
|
||||
rpits: FxIndexSet<LocalDefId>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for RPITVisitor {
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
|
||||
if let hir::TyKind::OpaqueDef(opaq) = ty.kind
|
||||
&& self.rpits.insert(opaq.def_id)
|
||||
{
|
||||
for bound in opaq.bounds {
|
||||
intravisit::walk_param_bound(self, bound);
|
||||
}
|
||||
}
|
||||
intravisit::walk_ty(self, ty)
|
||||
}
|
||||
}
|
||||
|
||||
let mut visitor = RPITVisitor { rpits: FxIndexSet::default() };
|
||||
|
||||
if let Some(output) = tcx.hir_get_fn_output(fn_def_id) {
|
||||
|
|
@ -246,9 +246,23 @@ fn associated_type_for_impl_trait_in_trait(
|
|||
let trait_def_id = tcx.local_parent(fn_def_id);
|
||||
assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait);
|
||||
|
||||
// Collect all opaque types in return position for the method and use
|
||||
// the index as the disambiguator to make an unique def path.
|
||||
let mut visitor = RPITVisitor { rpits: FxIndexSet::default() };
|
||||
visitor.visit_fn_ret_ty(tcx.hir_get_fn_output(fn_def_id).unwrap());
|
||||
let disambiguator = visitor.rpits.get_index_of(&opaque_ty_def_id).unwrap().try_into().unwrap();
|
||||
|
||||
let span = tcx.def_span(opaque_ty_def_id);
|
||||
// No name because this is an anonymous associated type.
|
||||
let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, None, DefKind::AssocTy);
|
||||
// Also use the method name to create an unique def path.
|
||||
let data = DefPathData::AnonAssocTy(tcx.item_name(fn_def_id.to_def_id()));
|
||||
let trait_assoc_ty = tcx.at(span).create_def(
|
||||
trait_def_id,
|
||||
// No name because this is an anonymous associated type.
|
||||
None,
|
||||
DefKind::AssocTy,
|
||||
Some(data),
|
||||
&mut DisambiguatorState::with(trait_def_id, data, disambiguator),
|
||||
);
|
||||
|
||||
let local_def_id = trait_assoc_ty.def_id();
|
||||
let def_id = local_def_id.to_def_id();
|
||||
|
|
@ -299,8 +313,22 @@ fn associated_type_for_impl_trait_in_impl(
|
|||
hir::FnRetTy::DefaultReturn(_) => tcx.def_span(impl_fn_def_id),
|
||||
hir::FnRetTy::Return(ty) => ty.span,
|
||||
};
|
||||
// No name because this is an anonymous associated type.
|
||||
let impl_assoc_ty = tcx.at(span).create_def(impl_local_def_id, None, DefKind::AssocTy);
|
||||
|
||||
// Use the same disambiguator and method name as the anon associated type in the trait.
|
||||
let disambiguated_data = tcx.def_key(trait_assoc_def_id).disambiguated_data;
|
||||
let DefPathData::AnonAssocTy(name) = disambiguated_data.data else {
|
||||
bug!("expected anon associated type")
|
||||
};
|
||||
let data = DefPathData::AnonAssocTy(name);
|
||||
|
||||
let impl_assoc_ty = tcx.at(span).create_def(
|
||||
impl_local_def_id,
|
||||
// No name because this is an anonymous associated type.
|
||||
None,
|
||||
DefKind::AssocTy,
|
||||
Some(data),
|
||||
&mut DisambiguatorState::with(impl_local_def_id, data, disambiguated_data.disambiguator),
|
||||
);
|
||||
|
||||
let local_def_id = impl_assoc_ty.def_id();
|
||||
let def_id = local_def_id.to_def_id();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::{anon_assoc#0}`
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:22:25
|
||||
|
|
||||
LL | reuse to_reuse::opaque_ret;
|
||||
|
|
@ -9,7 +9,7 @@ note: ...which requires comparing an impl and trait method signature, inferring
|
|||
|
|
||||
LL | reuse to_reuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::{anon_assoc#0}`, completing the cycle
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:21:5: 21:24>` is well-formed
|
||||
--> $DIR/unsupported.rs:21:5
|
||||
|
|
||||
|
|
@ -17,7 +17,7 @@ LL | impl ToReuse for u8 {
|
|||
| ^^^^^^^^^^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::{anon_assoc#0}`
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::opaque_ret::{anon_assoc#0}`
|
||||
--> $DIR/unsupported.rs:25:24
|
||||
|
|
||||
LL | reuse ToReuse::opaque_ret;
|
||||
|
|
@ -28,7 +28,7 @@ note: ...which requires comparing an impl and trait method signature, inferring
|
|||
|
|
||||
LL | reuse ToReuse::opaque_ret;
|
||||
| ^^^^^^^^^^
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::{anon_assoc#0}`, completing the cycle
|
||||
= note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>::opaque_ret::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:24:5: 24:25>` is well-formed
|
||||
--> $DIR/unsupported.rs:24:5
|
||||
|
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ LL | fn bar() -> () {}
|
|||
|
|
||||
= help: the trait `std::fmt::Display` is not implemented for `()`
|
||||
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
|
||||
note: required by a bound in `Foo::{anon_assoc#0}`
|
||||
note: required by a bound in `Foo::bar::{anon_assoc#0}`
|
||||
--> $DIR/doesnt-satisfy.rs:2:22
|
||||
|
|
||||
LL | fn bar() -> impl std::fmt::Display;
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{anon_assoc#0}`
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::bar::{anon_assoc#0}`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ trait Foo {
|
|||
}
|
||||
|
||||
fn hello<'s, T: Foo>(x: &'s T) -> impl Sized + use<'s, T> {
|
||||
//~^ ERROR <T as Foo>::{anon_assoc#0}<'s/#1>
|
||||
//~^ ERROR <T as Foo>::hello::{anon_assoc#0}<'s/#1>
|
||||
x.hello()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: <T as Foo>::{anon_assoc#0}<'s/#1>
|
||||
error: <T as Foo>::hello::{anon_assoc#0}<'s/#1>
|
||||
--> $DIR/dump.rs:10:35
|
||||
|
|
||||
LL | fn hello<'s, T: Foo>(x: &'s T) -> impl Sized + use<'s, T> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`
|
||||
error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`
|
||||
--> $DIR/method-compatability-via-leakage-cycle.rs:21:24
|
||||
|
|
||||
LL | fn foo(b: bool) -> impl Sized {
|
||||
|
|
@ -45,7 +45,7 @@ note: ...which requires type-checking `<impl at $DIR/method-compatability-via-le
|
|||
|
|
||||
LL | fn foo(b: bool) -> impl Sized {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`, completing the cycle
|
||||
= note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking that `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>` is well-formed
|
||||
--> $DIR/method-compatability-via-leakage-cycle.rs:17:1
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`
|
||||
error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`
|
||||
--> $DIR/method-compatability-via-leakage-cycle.rs:21:24
|
||||
|
|
||||
LL | fn foo(b: bool) -> impl Sized {
|
||||
|
|
@ -49,7 +49,7 @@ note: ...which requires type-checking `<impl at $DIR/method-compatability-via-le
|
|||
|
|
||||
LL | fn foo(b: bool) -> impl Sized {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`, completing the cycle
|
||||
= note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking that `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>` is well-formed
|
||||
--> $DIR/method-compatability-via-leakage-cycle.rs:17:1
|
||||
|
|
||||
|
|
@ -57,7 +57,7 @@ LL | impl Trait for u32 {
|
|||
| ^^^^^^^^^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`
|
||||
error[E0391]: cycle detected when computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`
|
||||
--> $DIR/method-compatability-via-leakage-cycle.rs:21:24
|
||||
|
|
||||
LL | fn foo(b: bool) -> impl Sized {
|
||||
|
|
@ -108,7 +108,7 @@ note: ...which requires type-checking `<impl at $DIR/method-compatability-via-le
|
|||
|
|
||||
LL | fn foo(b: bool) -> impl Sized {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::{anon_assoc#0}`, completing the cycle
|
||||
= note: ...which again requires computing type of `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>::foo::{anon_assoc#0}`, completing the cycle
|
||||
note: cycle used when checking that `<impl at $DIR/method-compatability-via-leakage-cycle.rs:17:1: 17:19>` is well-formed
|
||||
--> $DIR/method-compatability-via-leakage-cycle.rs:17:1
|
||||
|
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ LL | fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
|
|||
| ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
|
||||
|
|
||||
= help: the trait `Foo<char>` is implemented for `Bar`
|
||||
note: required by a bound in `Foo::{anon_assoc#0}`
|
||||
note: required by a bound in `Foo::foo::{anon_assoc#0}`
|
||||
--> $DIR/return-dont-satisfy-bounds.rs:2:30
|
||||
|
|
||||
LL | fn foo<F2>(self) -> impl Foo<T>;
|
||||
| ^^^^^^ required by this bound in `Foo::{anon_assoc#0}`
|
||||
| ^^^^^^ required by this bound in `Foo::foo::{anon_assoc#0}`
|
||||
|
||||
error[E0277]: the trait bound `Bar: Foo<u8>` is not satisfied
|
||||
--> $DIR/return-dont-satisfy-bounds.rs:8:34
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ error[E0277]: the trait bound `Something: Termination` is not satisfied
|
|||
LL | fn main() -> Something {
|
||||
| ^^^^^^^^^ the trait `Termination` is not implemented for `Something`
|
||||
|
|
||||
note: required by a bound in `Main::{anon_assoc#0}`
|
||||
note: required by a bound in `Main::main::{anon_assoc#0}`
|
||||
--> $DIR/issue-103052-2.rs:3:27
|
||||
|
|
||||
LL | fn main() -> impl std::process::Termination;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::{anon_assoc#0}`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{anon_assoc#0}`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue