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
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2791,7 +2791,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ExprKind::ConstBlock(anon_const) => {
let def_id = self.local_def_id(anon_const.id);
assert_eq!(DefKind::AnonConst, self.tcx.def_kind(def_id));
assert_eq!(DefKind::InlineConst, self.tcx.def_kind(def_id));
self.lower_anon_const_to_const_arg(anon_const, span)
}
_ => overly_complex_const(self),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/universal_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {

BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => {
match tcx.def_kind(self.mir_def) {
DefKind::InlineConst => {
DefKind::InlineConst if !tcx.is_type_system_inline_const(self.mir_def) => {
// This is required for `AscribeUserType` canonical query, which will call
// `type_of(inline_const_def_id)`. That `type_of` would inject erased lifetimes
// into borrowck, which is ICE #78174.
Expand Down
37 changes: 0 additions & 37 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,43 +448,6 @@ impl DefKind {
| DefKind::ExternCrate => false,
}
}

/// Returns `true` if `self` is a kind of definition that does not have its own
/// type-checking context, i.e. closure, coroutine or inline const.
#[inline]
pub fn is_typeck_child(self) -> bool {
match self {
DefKind::Closure | DefKind::InlineConst | DefKind::SyntheticCoroutineBody => true,
DefKind::Mod
| DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::Variant
| DefKind::Trait
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::AssocTy
| DefKind::TyParam
| DefKind::Fn
| DefKind::Const { .. }
| DefKind::ConstParam
| DefKind::Static { .. }
| DefKind::Ctor(_, _)
| DefKind::AssocFn
| DefKind::AssocConst { .. }
| DefKind::Macro(_)
| DefKind::ExternCrate
| DefKind::Use
| DefKind::ForeignMod
| DefKind::AnonConst
| DefKind::OpaqueTy
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm
| DefKind::Impl { .. } => false,
}
}
}

/// The resolution of a path or export.
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//! crate as a kind of pass. This should eventually be factored away.

use std::cell::Cell;
use std::{assert_matches, iter};
use std::{assert_matches, debug_assert_matches, iter};

use rustc_abi::{ExternAbi, Size};
use rustc_ast::Recovered;
Expand Down Expand Up @@ -1635,10 +1635,12 @@ fn const_param_default<'tcx>(
}

fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKind {
debug_assert_matches!(tcx.def_kind(def), DefKind::AnonConst | DefKind::InlineConst);
let hir_id = tcx.local_def_id_to_hir_id(def);
let const_arg_id = tcx.parent_hir_id(hir_id);
match tcx.hir_node(const_arg_id) {
hir::Node::ConstArg(_) => {
hir::Node::ConstArg(const_arg) => {
debug_assert_matches!(const_arg.kind, hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) if *def_id == def);
let parent_hir_node = tcx.hir_node(tcx.parent_hir_id(const_arg_id));
if tcx.features().generic_const_exprs() {
ty::AnonConstKind::GCE
Expand Down
12 changes: 4 additions & 8 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let tcx = self.tcx();
let parent_def_id = self.item_def_id();
if let Res::Def(DefKind::ConstParam, _) = res
&& tcx.def_kind(parent_def_id) == DefKind::AnonConst
&& matches!(tcx.def_kind(parent_def_id), DefKind::AnonConst | DefKind::InlineConst)
&& let ty::AnonConstKind::MCG = tcx.anon_const_kind(parent_def_id)
{
let folder = ForbidParamUsesFolder {
Expand Down Expand Up @@ -511,15 +511,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Inline consts and closures can be nested inside anon consts that forbid generic
// params (e.g. an enum discriminant). Walk up the def parent chain to find the
// nearest enclosing AnonConst and use that to determine the context.
let parent_def_id = tcx.typeck_root_def_id(parent_def_id.into());

let anon_const_def_id = match tcx.def_kind(parent_def_id) {
DefKind::AnonConst => parent_def_id,
DefKind::InlineConst | DefKind::Closure => {
let root = tcx.typeck_root_def_id(parent_def_id.into());
match tcx.def_kind(root) {
DefKind::AnonConst => root.expect_local(),
_ => return None,
}
}
DefKind::InlineConst if tcx.is_type_system_inline_const(parent_def_id) => parent_def_id,
_ => return None,
};

Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,13 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
}
_ => (),
}
// Skip `AnonConst`s because we feed their `type_of`.
// Skip `AnonConst`s and type system `InlineConst`s because we feed their `type_of` in
// `feed_anon_const_type`.
// Also skip items for which typeck forwards to parent typeck.
if !(matches!(def_kind, DefKind::AnonConst) || def_kind.is_typeck_child()) {
if !(def_kind == DefKind::AnonConst
|| def_kind == DefKind::InlineConst && tcx.is_type_system_inline_const(item_def_id)
|| tcx.is_typeck_child(item_def_id.to_def_id()))
{
tcx.ensure_ok().typeck(item_def_id);
}
// Ensure we generate the new `DefId` before finishing `check_crate`.
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_hir_typeck/src/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir
CheckLoopVisitor { tcx, cx_stack: vec![Normal], block_breaks: Default::default() };
let cx = match tcx.def_kind(def_id) {
DefKind::AnonConst => AnonConst,
DefKind::InlineConst => {
// only type system inline consts are typeck roots
debug_assert!(tcx.is_type_system_inline_const(def_id));
ConstBlock
}
_ => Fn,
};
check.with_context(cx, |v| v.visit_body(body));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1624,7 +1624,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
<- tcx.explicit_implied_const_bounds(def_id).skip_binder());
}
}
if let DefKind::AnonConst = def_kind {
if let DefKind::AnonConst | DefKind::InlineConst = def_kind {
record!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id));
}
if should_encode_const_of_item(self.tcx, def_id, def_kind) {
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_middle/src/hir/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, with_metavar_spans};
use crate::hir::{ModuleItems, ProjectedMaybeOwner, nested_filter};
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::query::{IntoQueryKey, LocalCrate};
use crate::ty::TyCtxt;
use crate::ty::{self, TyCtxt};

/// An iterator that walks up the ancestor tree of a given `HirId`.
/// Constructed using `tcx.hir_parent_iter(hir_id)`.
Expand Down Expand Up @@ -1115,6 +1115,12 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

pub fn is_type_system_inline_const(self, def_id: impl IntoQueryKey<DefId>) -> bool {
let def_id = def_id.into_query_key();
debug_assert_eq!(self.def_kind(def_id), DefKind::InlineConst);
self.anon_const_kind(def_id) != ty::AnonConstKind::NonTypeSystem
}

pub fn hir_maybe_get_struct_pattern_shorthand_field(self, expr: &Expr<'_>) -> Option<Symbol> {
let local = match expr {
Expr {
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,14 @@ impl<'tcx> TyCtxt<'tcx> {
/// effect. However, we do not want this as a general capability, so this interface restricts
/// to the only allowed case.
pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<'tcx, Ty<'tcx>>) {
debug_assert_eq!(self.def_kind(key), DefKind::AnonConst);
if cfg!(debug_assertions) {
match self.def_kind(key) {
DefKind::AnonConst => (),
DefKind::InlineConst => assert!(self.is_type_system_inline_const(key)),
def_kind => bug!("unexpected DefKind in feed_anon_const_type: {def_kind:?}"),
}
}

TyCtxtFeed { tcx: self, key }.type_of(value)
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/context/impl_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy { def_id },
DefKind::TyAlias => ty::AliasTermKind::FreeTy { def_id },
DefKind::Const { .. } => ty::AliasTermKind::FreeConst { def_id },
DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
DefKind::AnonConst | DefKind::InlineConst | DefKind::Ctor(_, CtorKind::Const) => {
ty::AliasTermKind::AnonConst { def_id }
}
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
Expand Down
33 changes: 32 additions & 1 deletion compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,38 @@ impl<'tcx> TyCtxt<'tcx> {
/// Returns `true` if `def_id` refers to a definition that does not have its own
/// type-checking context, i.e. closure, coroutine or inline const.
pub fn is_typeck_child(self, def_id: DefId) -> bool {
self.def_kind(def_id).is_typeck_child()
match self.def_kind(def_id) {
DefKind::InlineConst => !self.is_type_system_inline_const(def_id),
DefKind::Closure | DefKind::SyntheticCoroutineBody => true,
DefKind::Mod
| DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::Variant
| DefKind::Trait
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::AssocTy
| DefKind::TyParam
| DefKind::Fn
| DefKind::Const { .. }
| DefKind::ConstParam
| DefKind::Static { .. }
| DefKind::Ctor(_, _)
| DefKind::AssocFn
| DefKind::AssocConst { .. }
| DefKind::Macro(_)
| DefKind::ExternCrate
| DefKind::Use
| DefKind::ForeignMod
| DefKind::AnonConst
| DefKind::OpaqueTy
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm
| DefKind::Impl { .. } => false,
}
}

/// Returns `true` if `def_id` refers to a trait (i.e., `trait Foo { ... }`).
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_mir_transform/src/trivial_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,10 @@ where
F: FnOnce() -> B,
B: Deref<Target = Body<'tcx>>,
{
if !matches!(
tcx.def_kind(def),
DefKind::AssocConst { .. } | DefKind::Const { .. } | DefKind::AnonConst
) {
return None;
match tcx.def_kind(def) {
DefKind::AssocConst { .. } | DefKind::Const { .. } | DefKind::AnonConst => (),
DefKind::InlineConst if tcx.is_type_system_inline_const(def) => (),
_ => return None,
}

// If there are impossible predicates then MIR passes will replace the body with
Expand Down
84 changes: 22 additions & 62 deletions compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ use tracing::{debug, instrument};

use crate::macros::MacroRulesScopeRef;
use crate::{
ConstArgContext, ImplTraitContext, InvocationParent, ParentScope, Resolver, with_owner,
with_owner_tables,
ImplTraitContext, InvocationParent, ParentScope, Resolver, with_owner, with_owner_tables,
};

pub(crate) fn collect_definitions<'ra>(
Expand Down Expand Up @@ -115,12 +114,6 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
self.invocation_parent.impl_trait_context = orig_itc;
}

fn with_const_arg<F: FnOnce(&mut Self)>(&mut self, ctxt: ConstArgContext, f: F) {
let orig = mem::replace(&mut self.invocation_parent.const_arg_context, ctxt);
f(self);
self.invocation_parent.const_arg_context = orig;
}

fn collect_field(&mut self, field: &'a FieldDef, index: Option<usize>) {
let index = |this: &Self| {
index.unwrap_or_else(|| {
Expand Down Expand Up @@ -430,6 +423,9 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
}

fn visit_anon_const(&mut self, constant: &'a AnonConst) {
// Note that `visit_anon_const` is skipped for AnonConst nodes wrapped in an
// ExprKind::ConstBlock - these are handled in visit_expr, and are DefKind::InlineConst.

// `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so
// to avoid affecting stable we have to feature gate the not creating
// anon consts
Expand All @@ -441,16 +437,12 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
}

match constant.mgca_disambiguation {
MgcaDisambiguation::Direct => self.with_const_arg(ConstArgContext::Direct, |this| {
visit::walk_anon_const(this, constant);
}),
MgcaDisambiguation::Direct => visit::walk_anon_const(self, constant),
MgcaDisambiguation::AnonConst => {
self.with_const_arg(ConstArgContext::NonDirect, |this| {
let parent = this
.create_def(constant.id, None, DefKind::AnonConst, constant.value.span)
.def_id();
this.with_parent(parent, |this| visit::walk_anon_const(this, constant));
})
let parent = self
.create_def(constant.id, None, DefKind::AnonConst, constant.value.span)
.def_id();
self.with_parent(parent, |this| visit::walk_anon_const(this, constant));
}
};
}
Expand All @@ -459,60 +451,28 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
fn visit_expr(&mut self, expr: &'a Expr) {
debug!(?self.invocation_parent);

let parent_def = match &expr.kind {
match &expr.kind {
ExprKind::MacCall(..) => {
self.visit_macro_invoc(expr.id);
self.visit_invoc(expr.id);
return;
}
ExprKind::Closure(..) | ExprKind::Gen(..) => {
self.create_def(expr.id, None, DefKind::Closure, expr.span).def_id()
let def = self.create_def(expr.id, None, DefKind::Closure, expr.span).def_id();
self.with_parent(def, |this| visit::walk_expr(this, expr));
}
ExprKind::ConstBlock(constant) => {
// Under `min_generic_const_args` a `const { }` block sometimes
// corresponds to an anon const rather than an inline const.
let def_kind = match self.invocation_parent.const_arg_context {
ConstArgContext::Direct => DefKind::AnonConst,
ConstArgContext::NonDirect => DefKind::InlineConst,
};

return self.with_const_arg(ConstArgContext::NonDirect, |this| {
for attr in &expr.attrs {
visit::walk_attribute(this, attr);
}

let def =
this.create_def(constant.id, None, def_kind, constant.value.span).def_id();
this.with_parent(def, |this| visit::walk_anon_const(this, constant));
});
}

// Avoid overwriting `const_arg_context` as we may want to treat const blocks
// as being anon consts if we are inside a const argument.
ExprKind::Struct(_) | ExprKind::Call(..) | ExprKind::Tup(..) | ExprKind::Array(..) => {
return visit::walk_expr(self, expr);
}
// FIXME(mgca): we may want to handle block labels in some manner
ExprKind::Block(block, _) if let [stmt] = block.stmts.as_slice() => match stmt.kind {
// FIXME(mgca): this probably means that mac calls that expand
// to semi'd const blocks are handled differently to just writing
// out a semi'd const block.
StmtKind::Expr(..) | StmtKind::MacCall(..) => return visit::walk_expr(self, expr),

// Fallback to normal behaviour
StmtKind::Let(..) | StmtKind::Item(..) | StmtKind::Semi(..) | StmtKind::Empty => {
self.invocation_parent.parent_def
for attr in &expr.attrs {
visit::walk_attribute(self, attr);
}
},

_ => self.invocation_parent.parent_def,
};

self.with_const_arg(ConstArgContext::NonDirect, |this| {
// Note in some cases the `parent_def` here may be the existing parent
// and this is actually a no-op `with_parent` call.
this.with_parent(parent_def, |this| visit::walk_expr(this, expr))
})
let def = self
.create_def(constant.id, None, DefKind::InlineConst, constant.value.span)
.def_id();
// use specifically walk_anon_const, not walk_expr, to skip self.visit_anon_const
self.with_parent(def, |this| visit::walk_anon_const(this, constant));
}
_ => visit::walk_expr(self, expr),
}
}

fn visit_ty(&mut self, ty: &'a Ty) {
Expand Down
Loading
Loading