diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 7a45d909d0779..8e801ebc2f912 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1392,7 +1392,7 @@ pub enum ExprKind {
/// An array (e.g, `[a, b, c, d]`).
Array(ThinVec
>),
/// Allow anonymous constants from an inline `const` block
- ConstBlock(P),
+ ConstBlock(AnonConst),
/// A function call
///
/// The first field resolves to the function itself,
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 5c581c270e498..635f0f0345039 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1411,7 +1411,7 @@ pub fn noop_visit_expr(
match kind {
ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis),
ExprKind::ConstBlock(anon_const) => {
- vis.visit_expr(anon_const);
+ vis.visit_anon_const(anon_const);
}
ExprKind::Repeat(expr, count) => {
vis.visit_expr(expr);
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index b2f3b27c77e90..247053550d286 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -954,7 +954,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
ExprKind::Array(subexpressions) => {
walk_list!(visitor, visit_expr, subexpressions);
}
- ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_expr(anon_const)),
+ ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)),
ExprKind::Repeat(element, count) => {
try_visit!(visitor.visit_expr(element));
try_visit!(visitor.visit_anon_const(count));
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index eb206a09be313..a553109092842 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -75,8 +75,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
let kind = match &e.kind {
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
ExprKind::ConstBlock(c) => {
- self.has_inline_consts = true;
- hir::ExprKind::ConstBlock(self.lower_expr(c))
+ let c = self.with_new_scopes(c.value.span, |this| hir::ConstBlock {
+ def_id: this.local_def_id(c.id),
+ hir_id: this.lower_node_id(c.id),
+ body: this.lower_const_body(c.value.span, Some(&c.value)),
+ });
+ hir::ExprKind::ConstBlock(c)
}
ExprKind::Repeat(expr, count) => {
let expr = self.lower_expr(expr);
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 741a44eb0c523..44f37b5533a67 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -236,6 +236,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
+ fn visit_inline_const(&mut self, constant: &'hir ConstBlock) {
+ self.insert(DUMMY_SP, constant.hir_id, Node::ConstBlock(constant));
+
+ self.with_parent(constant.hir_id, |this| {
+ intravisit::walk_inline_const(this, constant);
+ });
+ }
+
fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 5a80fa803f840..201dffb629a16 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -96,8 +96,6 @@ struct LoweringContext<'a, 'hir> {
/// Bodies inside the owner being lowered.
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
- /// Whether there were inline consts that typeck will split out into bodies
- has_inline_consts: bool,
/// Attributes inside the owner being lowered.
attrs: SortedMap,
/// Collect items that were created by lowering the current owner.
@@ -160,7 +158,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
item_local_id_counter: hir::ItemLocalId::ZERO,
node_id_to_local_id: Default::default(),
trait_map: Default::default(),
- has_inline_consts: false,
// Lowering state.
catch_scope: None,
@@ -570,7 +567,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let current_attrs = std::mem::take(&mut self.attrs);
let current_bodies = std::mem::take(&mut self.bodies);
- let current_has_inline_consts = std::mem::take(&mut self.has_inline_consts);
let current_node_ids = std::mem::take(&mut self.node_id_to_local_id);
let current_trait_map = std::mem::take(&mut self.trait_map);
let current_owner =
@@ -597,7 +593,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.attrs = current_attrs;
self.bodies = current_bodies;
- self.has_inline_consts = current_has_inline_consts;
self.node_id_to_local_id = current_node_ids;
self.trait_map = current_trait_map;
self.current_hir_id_owner = current_owner;
@@ -634,7 +629,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let attrs = std::mem::take(&mut self.attrs);
let mut bodies = std::mem::take(&mut self.bodies);
let trait_map = std::mem::take(&mut self.trait_map);
- let has_inline_consts = std::mem::take(&mut self.has_inline_consts);
#[cfg(debug_assertions)]
for (id, attrs) in attrs.iter() {
@@ -652,7 +646,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.tcx.hash_owner_nodes(node, &bodies, &attrs);
let num_nodes = self.item_local_id_counter.as_usize();
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
- let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies, has_inline_consts };
+ let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 993ccc5b95609..1e117c46b6e29 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -380,9 +380,8 @@ impl<'a> State<'a> {
ast::ExprKind::Array(exprs) => {
self.print_expr_vec(exprs);
}
- ast::ExprKind::ConstBlock(expr) => {
- self.word_space("const");
- self.print_expr(expr, FixupContext::default());
+ ast::ExprKind::ConstBlock(anon_const) => {
+ self.print_expr_anon_const(anon_const, attrs);
}
ast::ExprKind::Repeat(element, count) => {
self.print_expr_repeat(element, count);
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 394c810176ab2..dcafac21bc742 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -288,6 +288,29 @@ fn produce_final_output_artifacts(
}
}
+ if sess.opts.json_artifact_notifications {
+ if codegen_results.modules.len() == 1 {
+ codegen_results.modules[0].for_each_output(|_path, ty| {
+ if sess.opts.output_types.contains_key(&ty) {
+ let descr = ty.shorthand();
+ // for single cgu file is renamed to drop cgu specific suffix
+ // so we regenerate it the same way
+ let path = crate_output.path(ty);
+ sess.dcx().emit_artifact_notification(path.as_path(), descr);
+ }
+ });
+ } else {
+ for module in &codegen_results.modules {
+ module.for_each_output(|path, ty| {
+ if sess.opts.output_types.contains_key(&ty) {
+ let descr = ty.shorthand();
+ sess.dcx().emit_artifact_notification(&path, descr);
+ }
+ });
+ }
+ }
+ }
+
// We leave the following files around by default:
// - #crate#.o
// - #crate#.crate.metadata.o
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index d57f4ddf8aaec..dec87db0fc5cd 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -717,6 +717,29 @@ fn produce_final_output_artifacts(
}
}
+ if sess.opts.json_artifact_notifications {
+ if compiled_modules.modules.len() == 1 {
+ compiled_modules.modules[0].for_each_output(|_path, ty| {
+ if sess.opts.output_types.contains_key(&ty) {
+ let descr = ty.shorthand();
+ // for single cgu file is renamed to drop cgu specific suffix
+ // so we regenerate it the same way
+ let path = crate_output.path(ty);
+ sess.dcx().emit_artifact_notification(path.as_path(), descr);
+ }
+ });
+ } else {
+ for module in &compiled_modules.modules {
+ module.for_each_output(|path, ty| {
+ if sess.opts.output_types.contains_key(&ty) {
+ let descr = ty.shorthand();
+ sess.dcx().emit_artifact_notification(&path, descr);
+ }
+ });
+ }
+ }
+ }
+
// We leave the following files around by default:
// - #crate#.o
// - #crate#.crate.metadata.o
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 1668104d7e22f..3b1921d40e6ba 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -106,6 +106,24 @@ pub struct CompiledModule {
pub llvm_ir: Option, // --emit=llvm-ir, llvm-bc is in bytecode
}
+impl CompiledModule {
+ /// Call `emit` function with every artifact type currently compiled
+ pub fn for_each_output(&self, mut emit: impl FnMut(&Path, OutputType)) {
+ if let Some(path) = self.object.as_deref() {
+ emit(path, OutputType::Object);
+ }
+ if let Some(path) = self.bytecode.as_deref() {
+ emit(path, OutputType::Bitcode);
+ }
+ if let Some(path) = self.llvm_ir.as_deref() {
+ emit(path, OutputType::LlvmAssembly);
+ }
+ if let Some(path) = self.assembly.as_deref() {
+ emit(path, OutputType::Assembly);
+ }
+ }
+}
+
pub struct CachedModuleCodegen {
pub name: String,
pub source: WorkProduct,
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index 3c11d67e74890..8c66888d1007e 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -38,6 +38,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
match node {
hir::Node::Ctor(_)
| hir::Node::AnonConst(_)
+ | hir::Node::ConstBlock(_)
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => {
hir::Constness::Const
}
@@ -56,7 +57,6 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
}
hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
- hir::Node::Expr(e) if let hir::ExprKind::ConstBlock(_) = e.kind => hir::Constness::Const,
_ => {
if let Some(fn_kind) = node.fn_kind() {
if fn_kind.constness() == hir::Constness::Const {
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 2a4859a2478dd..8de2cdefa81cd 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -177,8 +177,6 @@ declare_features! (
/// Allows using the `unadjusted` ABI; perma-unstable.
(internal, abi_unadjusted, "1.16.0", None),
- /// Allows using the `vectorcall` ABI.
- (unstable, abi_vectorcall, "1.7.0", None),
/// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
(internal, allocator_internals, "1.20.0", None),
/// Allows using `#[allow_internal_unsafe]`. This is an
@@ -243,6 +241,8 @@ declare_features! (
// feature-group-start: internal feature gates
// -------------------------------------------------------------------------
+ /// Allows using the `vectorcall` ABI.
+ (unstable, abi_vectorcall, "1.7.0", Some(124485)),
/// Allows features specific to auto traits.
/// Renamed from `optin_builtin_traits`.
(unstable, auto_traits, "1.50.0", Some(13231)),
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index e971d0e3c1435..ed344255a5eda 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -907,9 +907,6 @@ pub struct OwnerNodes<'tcx> {
pub nodes: IndexVec>,
/// Content of local bodies.
pub bodies: SortedMap>,
- /// Whether the body contains inline constants that are created for the query system during typeck
- /// of the body.
- pub has_inline_consts: bool,
}
impl<'tcx> OwnerNodes<'tcx> {
@@ -1626,6 +1623,14 @@ pub struct AnonConst {
pub span: Span,
}
+/// An inline constant expression `const { something }`.
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
+pub struct ConstBlock {
+ pub hir_id: HirId,
+ pub def_id: LocalDefId,
+ pub body: BodyId,
+}
+
/// An expression.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Expr<'hir> {
@@ -1912,7 +1917,7 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum ExprKind<'hir> {
/// Allow anonymous constants from an inline `const` block
- ConstBlock(&'hir Expr<'hir>),
+ ConstBlock(ConstBlock),
/// An array (e.g., `[a, b, c, d]`).
Array(&'hir [Expr<'hir>]),
/// A function call.
@@ -3644,6 +3649,7 @@ pub enum Node<'hir> {
Variant(&'hir Variant<'hir>),
Field(&'hir FieldDef<'hir>),
AnonConst(&'hir AnonConst),
+ ConstBlock(&'hir ConstBlock),
Expr(&'hir Expr<'hir>),
ExprField(&'hir ExprField<'hir>),
Stmt(&'hir Stmt<'hir>),
@@ -3704,6 +3710,7 @@ impl<'hir> Node<'hir> {
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
Node::Param(..)
| Node::AnonConst(..)
+ | Node::ConstBlock(..)
| Node::Expr(..)
| Node::Stmt(..)
| Node::Block(..)
@@ -3801,6 +3808,7 @@ impl<'hir> Node<'hir> {
}
Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
+ Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
_ => None,
}
@@ -3869,6 +3877,7 @@ impl<'hir> Node<'hir> {
expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
+ expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 9bc2bbe0c6471..4cadb899615b9 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -344,6 +344,9 @@ pub trait Visitor<'v>: Sized {
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
walk_anon_const(self, c)
}
+ fn visit_inline_const(&mut self, c: &'v ConstBlock) -> Self::Result {
+ walk_inline_const(self, c)
+ }
fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result {
walk_expr(self, ex)
}
@@ -716,6 +719,14 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo
visitor.visit_nested_body(constant.body)
}
+pub fn walk_inline_const<'v, V: Visitor<'v>>(
+ visitor: &mut V,
+ constant: &'v ConstBlock,
+) -> V::Result {
+ try_visit!(visitor.visit_id(constant.hir_id));
+ visitor.visit_nested_body(constant.body)
+}
+
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result {
try_visit!(visitor.visit_id(expression.hir_id));
match expression.kind {
@@ -723,7 +734,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
walk_list!(visitor, visit_expr, subexpressions);
}
ExprKind::ConstBlock(ref const_block) => {
- try_visit!(visitor.visit_expr(const_block))
+ try_visit!(visitor.visit_inline_const(const_block))
}
ExprKind::Repeat(ref element, ref count) => {
try_visit!(visitor.visit_expr(element));
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index 1ebd4b80e1835..baa1635f7313f 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -93,8 +93,7 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable for OwnerNodes<'
// `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing
// the body satisfies the condition of two nodes being different have different
// `hash_stable` results.
- let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _, has_inline_consts: _ } =
- *self;
+ let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _ } = *self;
opt_hash_including_bodies.unwrap().hash_stable(hcx, hasher);
}
}
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 30b03b43872a6..72e431926ca32 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -407,14 +407,11 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
match expr.kind {
// Manually recurse over closures and inline consts, because they are the only
// case of nested bodies that share the parent environment.
- hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
+ hir::ExprKind::Closure(&hir::Closure { body, .. })
+ | hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => {
let body = visitor.tcx.hir().body(body);
visitor.visit_body(body);
}
- hir::ExprKind::ConstBlock(expr) => visitor.enter_body(expr.hir_id, |this| {
- this.cx.var_parent = None;
- resolve_local(this, None, Some(expr));
- }),
hir::ExprKind::AssignOp(_, left_expr, right_expr) => {
debug!(
"resolve_expr - enabling pessimistic_yield, was previously {}",
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 9af959681fbfa..abdf85ad707bc 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -177,10 +177,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
}
}
}
- Node::Expr(&hir::Expr {
- kind: hir::ExprKind::Closure { .. } | hir::ExprKind::ConstBlock { .. },
- ..
- }) => Some(tcx.typeck_root_def_id(def_id.to_def_id())),
+ Node::ConstBlock(_)
+ | Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
+ Some(tcx.typeck_root_def_id(def_id.to_def_id()))
+ }
Node::Item(item) => match item.kind {
ItemKind::OpaqueTy(&hir::OpaqueTy {
origin:
@@ -415,7 +415,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
}
// provide junk type parameter defs for const blocks.
- if let Node::Expr(Expr { kind: ExprKind::ConstBlock(..), .. }) = node {
+ if let Node::ConstBlock(_) = node {
own_params.push(ty::GenericParamDef {
index: next_index(),
name: Symbol::intern(""),
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index c677fa9226160..505240d869c2d 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -485,7 +485,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
}
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
- Node::Expr(&Expr { kind: ExprKind::ConstBlock(..), .. }) => {
+
+ Node::ConstBlock(_) => {
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
args.as_inline_const().ty()
}
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 65b02a2ec5653..8fe81851f9327 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -190,6 +190,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
}
});
+ // Freeze definitions as we don't add new ones at this point. This improves performance by
+ // allowing lock-free access to them.
+ tcx.untracked().definitions.freeze();
+
// FIXME: Remove this when we implement creating `DefId`s
// for anon constants during their parents' typeck.
// Typeck all body owners in parallel will produce queries
@@ -201,10 +205,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
}
});
- // Freeze definitions as we don't add new ones at this point. This improves performance by
- // allowing lock-free access to them.
- tcx.untracked().definitions.freeze();
-
tcx.ensure().check_unused_traits(());
}
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index a8e0b3fc0793d..413d50dff514c 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -84,6 +84,7 @@ impl<'a> State<'a> {
Node::ImplItem(a) => self.print_impl_item(a),
Node::Variant(a) => self.print_variant(a),
Node::AnonConst(a) => self.print_anon_const(a),
+ Node::ConstBlock(a) => self.print_inline_const(a),
Node::Expr(a) => self.print_expr(a),
Node::ExprField(a) => self.print_expr_field(a),
Node::Stmt(a) => self.print_stmt(a),
@@ -1048,10 +1049,10 @@ impl<'a> State<'a> {
self.end()
}
- fn print_inline_const(&mut self, constant: &hir::Expr<'_>) {
+ fn print_inline_const(&mut self, constant: &hir::ConstBlock) {
self.ibox(INDENT_UNIT);
self.word_space("const");
- self.print_expr(constant);
+ self.ann.nested(self, Nested::Body(constant.body));
self.end()
}
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 3d88c4255245e..babf766f73b49 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -32,6 +32,7 @@ use rustc_errors::{
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId;
+use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{ExprKind, HirId, QPath};
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
@@ -335,7 +336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected),
ExprKind::Array(args) => self.check_expr_array(args, expected, expr),
- ExprKind::ConstBlock(ref block) => self.check_expr_with_expectation(block, expected),
+ ExprKind::ConstBlock(ref block) => self.check_expr_const_block(block, expected),
ExprKind::Repeat(element, ref count) => {
self.check_expr_repeat(element, count, expected, expr)
}
@@ -1459,6 +1460,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+ fn check_expr_const_block(
+ &self,
+ block: &'tcx hir::ConstBlock,
+ expected: Expectation<'tcx>,
+ ) -> Ty<'tcx> {
+ let body = self.tcx.hir().body(block.body);
+
+ // Create a new function context.
+ let def_id = block.def_id;
+ let fcx = FnCtxt::new(self, self.param_env, def_id);
+ crate::GatherLocalsVisitor::new(&fcx).visit_body(body);
+
+ let ty = fcx.check_expr_with_expectation(body.value, expected);
+ fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::ConstSized);
+ fcx.write_ty(block.hir_id, ty);
+ ty
+ }
+
fn check_expr_repeat(
&self,
element: &'tcx hir::Expr<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index caaf4142f7d1f..9ab89f3444c9c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1051,10 +1051,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.take_while(|(_, node)| {
// look at parents until we find the first body owner
node.body_id().is_none()
- && !matches!(
- node,
- Node::Expr(Expr { kind: ExprKind::ConstBlock { .. }, .. })
- )
})
.any(|(parent_id, _)| self.is_loop(parent_id));
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 4386e68ce8674..466397817dae1 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -149,6 +149,10 @@ impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> {
self.visit_body(body);
self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, capture_clause);
}
+ hir::ExprKind::ConstBlock(anon_const) => {
+ let body = self.fcx.tcx.hir().body(anon_const.body);
+ self.visit_body(body);
+ }
_ => {}
}
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index e337105f01104..8546ae6170c8b 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -3,7 +3,6 @@
// generic parameters.
use crate::FnCtxt;
-use hir::def::DefKind;
use rustc_data_structures::unord::ExtendUnord;
use rustc_errors::{ErrorGuaranteed, StashKey};
use rustc_hir as hir;
@@ -17,7 +16,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::TypeSuperFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_trait_selection::solve;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
@@ -296,11 +295,11 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
hir::ExprKind::Field(..) | hir::ExprKind::OffsetOf(..) => {
self.visit_field_id(e.hir_id);
}
- hir::ExprKind::ConstBlock(_) => {
- let feed = self.tcx().create_def(self.fcx.body_id, kw::Empty, DefKind::InlineConst);
- feed.def_span(e.span);
- feed.local_def_id_to_hir_id(e.hir_id);
- self.typeck_results.inline_consts.insert(e.hir_id.local_id, feed.def_id());
+ hir::ExprKind::ConstBlock(anon_const) => {
+ self.visit_node_id(e.span, anon_const.hir_id);
+
+ let body = self.tcx().hir().body(anon_const.body);
+ self.visit_body(body);
}
_ => {}
}
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 72c4e1b511e64..f8a2da06972ae 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -587,6 +587,7 @@ pub enum FixupError {
UnresolvedFloatTy(FloatVid),
UnresolvedTy(TyVid),
UnresolvedConst(ConstVid),
+ UnresolvedEffect(EffectVid),
}
/// See the `region_obligations` field for more information.
@@ -614,6 +615,7 @@ impl fmt::Display for FixupError {
),
UnresolvedTy(_) => write!(f, "unconstrained type"),
UnresolvedConst(_) => write!(f, "unconstrained const value"),
+ UnresolvedEffect(_) => write!(f, "unconstrained effect value"),
}
}
}
diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs
index 21ef2e89523f5..830d79f52b945 100644
--- a/compiler/rustc_infer/src/infer/resolve.rs
+++ b/compiler/rustc_infer/src/infer/resolve.rs
@@ -167,6 +167,9 @@ impl<'a, 'tcx> FallibleTypeFolder> for FullTypeResolver<'a, 'tcx> {
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
bug!("Unexpected const in full const resolver: {:?}", c);
}
+ ty::ConstKind::Infer(InferConst::EffectVar(evid)) => {
+ return Err(FixupError::UnresolvedEffect(evid));
+ }
_ => {}
}
c.try_super_fold_with(self)
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 639c98155e705..28371f2666097 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1,5 +1,3 @@
-use std::borrow::Cow;
-
use crate::hir::ModuleItems;
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::query::LocalCrate;
@@ -256,26 +254,13 @@ impl<'hir> Map<'hir> {
/// Given a `LocalDefId`, returns the `BodyId` associated with it,
/// if the node is a body owner, otherwise returns `None`.
- pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option>> {
- Some(match self.tcx.def_kind(id) {
- // Inline consts do not have bodies of their own, so create one to make the follow-up logic simpler.
- DefKind::InlineConst => {
- let e = self.expect_expr(self.tcx.local_def_id_to_hir_id(id));
- Cow::Owned(Body {
- params: &[],
- value: match e.kind {
- ExprKind::ConstBlock(body) => body,
- _ => span_bug!(e.span, "InlineConst was not a ConstBlock: {e:#?}"),
- },
- })
- }
- _ => Cow::Borrowed(self.body(self.tcx.hir_node_by_def_id(id).body_id()?)),
- })
+ pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<&'hir Body<'hir>> {
+ Some(self.body(self.tcx.hir_node_by_def_id(id).body_id()?))
}
/// Given a body owner's id, returns the `BodyId` associated with it.
#[track_caller]
- pub fn body_owned_by(self, id: LocalDefId) -> Cow<'hir, Body<'hir>> {
+ pub fn body_owned_by(self, id: LocalDefId) -> &'hir Body<'hir> {
self.maybe_body_owned_by(id).unwrap_or_else(|| {
let hir_id = self.tcx.local_def_id_to_hir_id(id);
span_bug!(
@@ -336,7 +321,7 @@ impl<'hir> Map<'hir> {
/// Returns an iterator of the `DefId`s for all body-owners in this
/// crate. If you would prefer to iterate over the bodies
- /// themselves, you can do `self.hir().krate().owners.iter()`.
+ /// themselves, you can do `self.hir().krate().body_ids.iter()`.
#[inline]
pub fn body_owners(self) -> impl Iterator- + 'hir {
self.tcx.hir_crate_items(()).body_owners.iter().copied()
@@ -523,17 +508,7 @@ impl<'hir> Map<'hir> {
/// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context.
/// Used exclusively for diagnostics, to avoid suggestion function calls.
pub fn is_inside_const_context(self, hir_id: HirId) -> bool {
- for (_, node) in self.parent_iter(hir_id) {
- if let Some((def_id, _)) = node.associated_body() {
- return self.body_const_context(def_id).is_some();
- }
- if let Node::Expr(e) = node {
- if let ExprKind::ConstBlock(_) = e.kind {
- return true;
- }
- }
- }
- false
+ self.body_const_context(self.enclosing_body_owner(hir_id)).is_some()
}
/// Retrieves the `HirId` for `id`'s enclosing function *if* the `id` block or return is
@@ -916,6 +891,7 @@ impl<'hir> Map<'hir> {
Node::Variant(variant) => variant.span,
Node::Field(field) => field.span,
Node::AnonConst(constant) => constant.span,
+ Node::ConstBlock(constant) => self.body(constant.body).value.span,
Node::Expr(expr) => expr.span,
Node::ExprField(field) => field.span,
Node::Stmt(stmt) => stmt.span,
@@ -1185,6 +1161,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id))
}
Node::AnonConst(_) => node_str("const"),
+ Node::ConstBlock(_) => node_str("const"),
Node::Expr(_) => node_str("expr"),
Node::ExprField(_) => node_str("expr field"),
Node::Stmt(_) => node_str("stmt"),
@@ -1334,6 +1311,11 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
intravisit::walk_anon_const(self, c)
}
+ fn visit_inline_const(&mut self, c: &'hir ConstBlock) {
+ self.body_owners.push(c.def_id);
+ intravisit::walk_inline_const(self, c)
+ }
+
fn visit_expr(&mut self, ex: &'hir Expr<'hir>) {
if let ExprKind::Closure(closure) = ex.kind {
self.body_owners.push(closure.def_id);
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 47f66c6440627..86d2a230f305c 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -743,7 +743,6 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1,
),
bodies,
- has_inline_consts: false,
})));
self.feed_owner_id().hir_attrs(attrs);
}
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 69ea9c9843a08..24e3e623ff274 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -217,10 +217,6 @@ pub struct TypeckResults<'tcx> {
/// Container types and field indices of `offset_of!` expressions
offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<(VariantIdx, FieldIdx)>)>,
-
- /// Maps from `HirId`s of const blocks (the `ExprKind::ConstBlock`, not the inner expression's)
- /// to the `DefId` of the corresponding inline const.
- pub inline_consts: FxIndexMap,
}
impl<'tcx> TypeckResults<'tcx> {
@@ -253,7 +249,6 @@ impl<'tcx> TypeckResults<'tcx> {
treat_byte_string_as_slice: Default::default(),
closure_size_eval: Default::default(),
offset_of_data: Default::default(),
- inline_consts: Default::default(),
}
}
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 14d1b502474fd..193f0d124bb80 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -568,8 +568,11 @@ fn construct_const<'a, 'tcx>(
..
}) => (*span, ty.span),
Node::AnonConst(ct) => (ct.span, ct.span),
- Node::Expr(&hir::Expr { span, kind: hir::ExprKind::ConstBlock(_), .. }) => (span, span),
- node => span_bug!(tcx.def_span(def), "can't build MIR for {def:?}: {node:#?}"),
+ Node::ConstBlock(_) => {
+ let span = tcx.def_span(def);
+ (span, span)
+ }
+ _ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def),
};
let infcx = tcx.infer_ctxt().build();
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index bd66257e6b687..28f9300b97a88 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -671,9 +671,9 @@ impl<'tcx> Cx<'tcx> {
ExprKind::OffsetOf { container, fields }
}
- hir::ExprKind::ConstBlock(body) => {
- let ty = self.typeck_results().node_type(body.hir_id);
- let did = self.typeck_results().inline_consts[&expr.hir_id.local_id].into();
+ hir::ExprKind::ConstBlock(ref anon_const) => {
+ let ty = self.typeck_results().node_type(anon_const.hir_id);
+ let did = anon_const.def_id.to_def_id();
let typeck_root_def_id = tcx.typeck_root_def_id(did);
let parent_args =
tcx.erase_regions(GenericArgs::identity_for_item(tcx, typeck_root_def_id));
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index bd9e34ae80fc4..244ac409fd381 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -165,7 +165,7 @@ impl<'tcx> Cx<'tcx> {
&'a mut self,
owner_id: HirId,
fn_decl: &'tcx hir::FnDecl<'tcx>,
- body: &hir::Body<'tcx>,
+ body: &'tcx hir::Body<'tcx>,
) -> impl Iterator
- > + 'a {
let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id];
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 33401cad631a1..7408c679f00b1 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -637,13 +637,15 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
/// Converts inline const patterns.
fn lower_inline_const(
&mut self,
- expr: &'tcx hir::Expr<'tcx>,
+ block: &'tcx hir::ConstBlock,
id: hir::HirId,
span: Span,
) -> PatKind<'tcx> {
let tcx = self.tcx;
- let def_id = self.typeck_results.inline_consts[&id.local_id];
- let ty = tcx.typeck(def_id).node_type(expr.hir_id);
+ let def_id = block.def_id;
+ let body_id = block.body;
+ let expr = &tcx.hir().body(body_id).value;
+ let ty = tcx.typeck(def_id).node_type(block.hir_id);
// Special case inline consts that are just literals. This is solely
// a performance optimization, as we could also just go through the regular
diff --git a/compiler/rustc_mir_transform/src/dump_mir.rs b/compiler/rustc_mir_transform/src/dump_mir.rs
index 13841be494cf0..3b71cf02c1a0a 100644
--- a/compiler/rustc_mir_transform/src/dump_mir.rs
+++ b/compiler/rustc_mir_transform/src/dump_mir.rs
@@ -28,6 +28,9 @@ pub fn emit_mir(tcx: TyCtxt<'_>) -> io::Result<()> {
OutFileName::Real(path) => {
let mut f = io::BufWriter::new(File::create(&path)?);
write_mir_pretty(tcx, None, &mut f)?;
+ if tcx.sess.opts.json_artifact_notifications {
+ tcx.dcx().emit_artifact_notification(&path, "mir");
+ }
}
}
Ok(())
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index fadb5edefdfb1..548e4e309360e 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -223,7 +223,6 @@ enum Value<'tcx> {
NullaryOp(NullOp<'tcx>, Ty<'tcx>),
UnaryOp(UnOp, VnIndex),
BinaryOp(BinOp, VnIndex, VnIndex),
- CheckedBinaryOp(BinOp, VnIndex, VnIndex), // FIXME get rid of this, work like MIR instead
Cast {
kind: CastKind,
value: VnIndex,
@@ -508,17 +507,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
let val = self.ecx.binary_op(bin_op, &lhs, &rhs).ok()?;
val.into()
}
- CheckedBinaryOp(bin_op, lhs, rhs) => {
- let lhs = self.evaluated[lhs].as_ref()?;
- let lhs = self.ecx.read_immediate(lhs).ok()?;
- let rhs = self.evaluated[rhs].as_ref()?;
- let rhs = self.ecx.read_immediate(rhs).ok()?;
- let val = self
- .ecx
- .binary_op(bin_op.wrapping_to_overflowing().unwrap(), &lhs, &rhs)
- .ok()?;
- val.into()
- }
Cast { kind, value, from: _, to } => match kind {
CastKind::IntToInt | CastKind::IntToFloat => {
let value = self.evaluated[value].as_ref()?;
@@ -829,17 +817,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
let lhs = lhs?;
let rhs = rhs?;
- if let Some(op) = op.overflowing_to_wrapping() {
- if let Some(value) = self.simplify_binary(op, true, ty, lhs, rhs) {
- return Some(value);
- }
- Value::CheckedBinaryOp(op, lhs, rhs)
- } else {
- if let Some(value) = self.simplify_binary(op, false, ty, lhs, rhs) {
- return Some(value);
- }
- Value::BinaryOp(op, lhs, rhs)
+ if let Some(value) = self.simplify_binary(op, ty, lhs, rhs) {
+ return Some(value);
}
+ Value::BinaryOp(op, lhs, rhs)
}
Rvalue::UnaryOp(op, ref mut arg) => {
let arg = self.simplify_operand(arg, location)?;
@@ -970,7 +951,6 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
fn simplify_binary(
&mut self,
op: BinOp,
- checked: bool,
lhs_ty: Ty<'tcx>,
lhs: VnIndex,
rhs: VnIndex,
@@ -999,22 +979,39 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
use Either::{Left, Right};
let a = as_bits(lhs).map_or(Right(lhs), Left);
let b = as_bits(rhs).map_or(Right(rhs), Left);
+
let result = match (op, a, b) {
// Neutral elements.
- (BinOp::Add | BinOp::BitOr | BinOp::BitXor, Left(0), Right(p))
+ (
+ BinOp::Add
+ | BinOp::AddWithOverflow
+ | BinOp::AddUnchecked
+ | BinOp::BitOr
+ | BinOp::BitXor,
+ Left(0),
+ Right(p),
+ )
| (
BinOp::Add
+ | BinOp::AddWithOverflow
+ | BinOp::AddUnchecked
| BinOp::BitOr
| BinOp::BitXor
| BinOp::Sub
+ | BinOp::SubWithOverflow
+ | BinOp::SubUnchecked
| BinOp::Offset
| BinOp::Shl
| BinOp::Shr,
Right(p),
Left(0),
)
- | (BinOp::Mul, Left(1), Right(p))
- | (BinOp::Mul | BinOp::Div, Right(p), Left(1)) => p,
+ | (BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked, Left(1), Right(p))
+ | (
+ BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::Div,
+ Right(p),
+ Left(1),
+ ) => p,
// Attempt to simplify `x & ALL_ONES` to `x`, with `ALL_ONES` depending on type size.
(BinOp::BitAnd, Right(p), Left(ones)) | (BinOp::BitAnd, Left(ones), Right(p))
if ones == layout.size.truncate(u128::MAX)
@@ -1023,10 +1020,21 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
p
}
// Absorbing elements.
- (BinOp::Mul | BinOp::BitAnd, _, Left(0))
+ (
+ BinOp::Mul | BinOp::MulWithOverflow | BinOp::MulUnchecked | BinOp::BitAnd,
+ _,
+ Left(0),
+ )
| (BinOp::Rem, _, Left(1))
| (
- BinOp::Mul | BinOp::Div | BinOp::Rem | BinOp::BitAnd | BinOp::Shl | BinOp::Shr,
+ BinOp::Mul
+ | BinOp::MulWithOverflow
+ | BinOp::MulUnchecked
+ | BinOp::Div
+ | BinOp::Rem
+ | BinOp::BitAnd
+ | BinOp::Shl
+ | BinOp::Shr,
Left(0),
_,
) => self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty),
@@ -1038,7 +1046,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
self.insert_scalar(Scalar::from_uint(ones, layout.size), lhs_ty)
}
// Sub/Xor with itself.
- (BinOp::Sub | BinOp::BitXor, a, b) if a == b => {
+ (BinOp::Sub | BinOp::SubWithOverflow | BinOp::SubUnchecked | BinOp::BitXor, a, b)
+ if a == b =>
+ {
self.insert_scalar(Scalar::from_uint(0u128, layout.size), lhs_ty)
}
// Comparison:
@@ -1052,7 +1062,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
_ => return None,
};
- if checked {
+ if op.is_overflowing() {
let false_val = self.insert_bool(false);
Some(self.insert_tuple(vec![result, false_val]))
} else {
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index a8741254ffbf7..9d88f8bf9bec7 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -222,16 +222,6 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet {
// All body-owners have MIR associated with them.
set.extend(tcx.hir().body_owners());
- // Inline consts' bodies are created in
- // typeck instead of during ast lowering, like all other bodies so far.
- for def_id in tcx.hir().body_owners() {
- // Incremental performance optimization: only load typeck results for things that actually have inline consts
- if tcx.hir_owner_nodes(tcx.hir().body_owned_by(def_id).id().hir_id.owner).has_inline_consts
- {
- set.extend(tcx.typeck(def_id).inline_consts.values())
- }
- }
-
// Additionally, tuple struct/variant constructors have MIR, but
// they don't have a BodyId, so we need to build them separately.
struct GatherCtors<'a> {
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index bab8b6c06ebee..c2183258eef14 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -25,8 +25,8 @@ use rustc_ast::tokenstream::{AttributesData, DelimSpacing, DelimSpan, Spacing};
use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor};
use rustc_ast::util::case::Case;
use rustc_ast::{
- self as ast, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind, DelimArgs, Expr,
- ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, Visibility,
+ self as ast, AnonConst, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind, DelimArgs,
+ Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, Visibility,
VisibilityKind, DUMMY_NODE_ID,
};
use rustc_ast_pretty::pprust;
@@ -1260,9 +1260,12 @@ impl<'a> Parser<'a> {
}
self.eat_keyword(kw::Const);
let (attrs, blk) = self.parse_inner_attrs_and_block()?;
- let expr = self.mk_expr(blk.span, ExprKind::Block(blk, None));
- let blk_span = expr.span;
- Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(expr), attrs))
+ let anon_const = AnonConst {
+ id: DUMMY_NODE_ID,
+ value: self.mk_expr(blk.span, ExprKind::Block(blk, None)),
+ };
+ let blk_span = anon_const.value.span;
+ Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(anon_const), attrs))
}
/// Parses mutability (`mut` or nothing).
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 71f3e8b7b5d9c..3f6eccbd5a523 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -196,6 +196,11 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon));
}
+ fn visit_inline_const(&mut self, block: &'tcx hir::ConstBlock) {
+ let kind = Some(hir::ConstContext::Const { inline: true });
+ self.recurse_into(kind, None, |this| intravisit::walk_inline_const(this, block));
+ }
+
fn visit_body(&mut self, body: &hir::Body<'tcx>) {
let owner = self.tcx.hir().body_owner_def_id(body.id());
let kind = self.tcx.hir().body_const_context(owner);
@@ -223,11 +228,6 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
self.const_check_violated(expr, e.span);
}
}
- hir::ExprKind::ConstBlock(expr) => {
- let kind = Some(hir::ConstContext::Const { inline: true });
- self.recurse_into(kind, None, |this| intravisit::walk_expr(this, expr));
- return;
- }
_ => {}
}
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 0049afff528ca..ddc50e2b811a2 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -587,16 +587,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
hir::ExprKind::OffsetOf(..) => {
self.handle_offset_of(expr);
}
- hir::ExprKind::ConstBlock(expr) => {
- // When inline const blocks are used in pattern position, paths
- // referenced by it should be considered as used.
- let in_pat = mem::replace(&mut self.in_pat, false);
-
- intravisit::walk_expr(self, expr);
-
- self.in_pat = in_pat;
- return;
- }
_ => (),
}
@@ -658,6 +648,17 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
self.in_pat = in_pat;
}
+
+ fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) {
+ // When inline const blocks are used in pattern position, paths
+ // referenced by it should be considered as used.
+ let in_pat = mem::replace(&mut self.in_pat, false);
+
+ self.live_symbols.insert(c.def_id);
+ intravisit::walk_inline_const(self, c);
+
+ self.in_pat = in_pat;
+ }
}
fn has_allow_dead_code_or_lang_attr(
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 698f15015c48c..dfa7dfa339817 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -147,11 +147,6 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) {
return;
}
- // Don't run for inline consts, they are collected together with their parent
- if let DefKind::InlineConst = tcx.def_kind(def_id) {
- return;
- }
-
// Don't run unused pass for #[naked]
if tcx.has_attr(def_id.to_def_id(), sym::naked) {
return;
@@ -1148,13 +1143,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
}
hir::ExprKind::Lit(..)
+ | hir::ExprKind::ConstBlock(..)
| hir::ExprKind::Err(_)
| hir::ExprKind::Path(hir::QPath::TypeRelative(..))
| hir::ExprKind::Path(hir::QPath::LangItem(..))
| hir::ExprKind::OffsetOf(..) => succ,
- hir::ExprKind::ConstBlock(expr) => self.propagate_through_expr(expr, succ),
-
// Note that labels have been resolved, so we don't need to look
// at the label ident
hir::ExprKind::Block(ref blk, _) => self.propagate_through_block(blk, succ),
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index 737310e5c04a3..2587a18b8c897 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -93,6 +93,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
self.with_context(Constant, |v| intravisit::walk_anon_const(v, c));
}
+ fn visit_inline_const(&mut self, c: &'hir hir::ConstBlock) {
+ self.with_context(Constant, |v| intravisit::walk_inline_const(v, c));
+ }
+
fn visit_fn(
&mut self,
fk: hir::intravisit::FnKind<'hir>,
@@ -285,9 +289,6 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
self.cx_stack.len() - 1,
)
}
- hir::ExprKind::ConstBlock(expr) => {
- self.with_context(Constant, |v| intravisit::walk_expr(v, expr));
- }
_ => intravisit::walk_expr(self, e),
}
}
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index cad10571afe62..bd0622428569c 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -325,6 +325,16 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
ExprKind::Gen(_, _, _) => {
self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span)
}
+ ExprKind::ConstBlock(ref constant) => {
+ let def = self.create_def(
+ constant.id,
+ kw::Empty,
+ DefKind::InlineConst,
+ constant.value.span,
+ );
+ self.with_parent(def, |this| visit::walk_anon_const(this, constant));
+ return;
+ }
_ => self.parent_def,
};
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index bcf2c9a920610..8b3af5093e5f9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -4505,10 +4505,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
self.visit_expr(elem);
self.resolve_anon_const(ct, AnonConstKind::ConstArg(IsRepeatExpr::Yes));
}
- ExprKind::ConstBlock(ref expr) => {
- self.resolve_anon_const_manual(false, AnonConstKind::InlineConst, |this| {
- this.visit_expr(expr)
- });
+ ExprKind::ConstBlock(ref ct) => {
+ self.resolve_anon_const(ct, AnonConstKind::InlineConst);
}
ExprKind::Index(ref elem, ref idx, _) => {
self.resolve_expr(elem, Some(expr));
diff --git a/library/alloc/tests/vec_deque_alloc_error.rs b/library/alloc/tests/vec_deque_alloc_error.rs
index c11f4556da9a6..8b516ddbc5c55 100644
--- a/library/alloc/tests/vec_deque_alloc_error.rs
+++ b/library/alloc/tests/vec_deque_alloc_error.rs
@@ -8,6 +8,7 @@ use std::{
};
#[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
fn test_shrink_to_unwind() {
// This tests that `shrink_to` leaves the deque in a consistent state when
// the call to `RawVec::shrink_to_fit` unwinds. The code is adapted from #123369
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index fbbd40bfb796a..a79a232e3d5b8 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -1910,8 +1910,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result {
// The code below ensures that `FreeOnDrop` is never a null pointer
unsafe {
// `copyfile_state_free` returns -1 if the `to` or `from` files
- // cannot be closed. However, this is not considered this an
- // error.
+ // cannot be closed. However, this is not considered an error.
libc::copyfile_state_free(self.0);
}
}
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 4ef2fcebe9283..201ace5ce3a7b 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -30,10 +30,15 @@
- [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
- [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md)
- [arm-none-eabi](platform-support/arm-none-eabi.md)
- - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)
- - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md)
- - [armv7r-none-eabi](platform-support/armv7r-none-eabi.md)
- - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md)
+ - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)
+ - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md)
+ - [armv7r-none-eabi](platform-support/armv7r-none-eabi.md)
+ - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md)
+ - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md)
+ - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md)
+ - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md)
+ - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md)
+ - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md)
- [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
- [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md)
- [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
@@ -60,11 +65,6 @@
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
- [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
- [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
- - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md)
- - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md)
- - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md)
- - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md)
- - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md)
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)
- [*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md)
diff --git a/src/doc/rustc/src/json.md b/src/doc/rustc/src/json.md
index 32083b2f731d8..c853f34ee036c 100644
--- a/src/doc/rustc/src/json.md
+++ b/src/doc/rustc/src/json.md
@@ -217,7 +217,8 @@ Diagnostics have the following format:
Artifact notifications are emitted when the [`--json=artifacts`
flag][option-json] is used. They indicate that a file artifact has been saved
to disk. More information about emit kinds may be found in the [`--emit`
-flag][option-emit] documentation.
+flag][option-emit] documentation. Notifications can contain more than one file
+for each type, for example when using multiple codegen units.
```javascript
{
@@ -229,6 +230,11 @@ flag][option-emit] documentation.
- "link": The generated crate as specified by the crate-type.
- "dep-info": The `.d` file with dependency information in a Makefile-like syntax.
- "metadata": The Rust `.rmeta` file containing metadata about the crate.
+ - "asm": The `.s` file with generated assembly
+ - "llvm-ir": The `.ll` file with generated textual LLVM IR
+ - "llvm-bc": The `.bc` file with generated LLVM bitcode
+ - "mir": The `.mir` file with rustc's mid-level intermediate representation.
+ - "obj": The `.o` file with generated native object code
*/
"emit": "link"
}
diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md
index 0b1b10e4762e7..de0ef322fa673 100644
--- a/src/doc/rustc/src/platform-support/arm-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md
@@ -1,6 +1,15 @@
# `{arm,thumb}*-none-eabi(hf)?`
-## Tier 2 Target List
+## Common Target Details
+
+This documentation covers details that apply to a range of bare-metal targets
+for 32-bit Arm CPUs. The `arm-none-eabi` flavor of the GNU compiler toolchain is
+often used to assist compilation to these targets.
+
+Details that apply only to only a specific target in this group are covered in
+their own document.
+
+### Tier 2 Target List
- Arm A-Profile Architectures
- `armv7a-none-eabi`
@@ -16,7 +25,7 @@
- *Legacy* Arm Architectures
- None
-## Tier 3 Target List
+### Tier 3 Target List
- Arm A-Profile Architectures
- `armv7a-none-eabihf`
@@ -28,24 +37,21 @@
- [`armv4t-none-eabi` and `thumbv4t-none-eabi`](armv4t-none-eabi.md)
- [`armv5te-none-eabi` and `thumbv5te-none-eabi`](armv5te-none-eabi.md)
-## Common Target Details
-
-This documentation covers details that apply to a range of bare-metal targets
-for 32-bit Arm CPUs. In addition, target specific details may be covered in
-their own document.
+## Instruction Sets
There are two 32-bit instruction set architectures (ISAs) defined by Arm:
- The [*A32 ISA*][a32-isa], with fixed-width 32-bit instructions. Previously
- known as the *Arm* ISA, this originated with the original ARM1 of 1985 and has
+ known as the *Arm* ISA, this originated with the original Arm1 of 1985 and has
been updated by various revisions to the architecture specifications ever
since.
- The [*T32 ISA*][t32-isa], with a mix of 16-bit and 32-bit width instructions.
Note that this term includes both the original 16-bit width *Thumb* ISA
introduced with the Armv4T architecture in 1994, and the later 16/32-bit sized
- *Thumb-2* ISA introduced with the Armv6T2 architecture in 2003. Again, these
- ISAs have been revised by subsequent revisions to the relevant Arm
- architecture specifications.
+ *Thumb-2* ISA introduced with the Armv6T2 architecture in 2003.
+
+Again, these ISAs have been revised by subsequent revisions to the relevant Arm
+architecture specifications.
There is also a 64-bit ISA with fixed-width 32-bit instructions called the *A64
ISA*, but targets which implement that instruction set generally start with
diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
index f4c8dd46f1d03..ab8b4caaadffa 100644
--- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
@@ -1,16 +1,13 @@
-# armv4t-none-eabi
+# armv4t-none-eabi / thumbv4t-none-eabi
Tier 3
-Bare-metal target for any cpu in the Armv4T architecture family, supporting
-ARM/Thumb code interworking (aka `A32`/`T32`), with ARM code as the default code
-generation.
+These two targets are part of the [`arm-none-eabi`](arm-none-eabi.md) target
+group, and all the information there applies.
-In particular this supports the Game Boy Advance (GBA), but there's nothing
-GBA-specific with this target, so any Armv4T device should work fine.
-
-See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
-`arm-none-eabi` targets.
+Both of these targets can be used on the Game Boy Advance (GBA), among other
+things. On the GBA, one should usually use the `thumb` target to get the best
+overall performance.
## Target Maintainers
@@ -23,6 +20,6 @@ This is a cross-compiled target that you will need to emulate during testing.
Because this is a device-agnostic target, and the exact emulator that you'll
need depends on the specific device you want to run your code on.
-For example, when programming for the Gameboy Advance, the
-[mgba-test-runner](https://github.com/agbrs/agb) program could be used to make a
-normal set of rust tests be run within the `mgba` emulator.
+* When building for the GBA, [mgba-test-runner](https://github.com/agbrs/agb)
+ can be used to make a normal set of rust tests be run within the `mgba`
+ emulator.
diff --git a/src/doc/unstable-book/src/language-features/abi-vectorcall.md b/src/doc/unstable-book/src/language-features/abi-vectorcall.md
new file mode 100644
index 0000000000000..56273bfdb791a
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/abi-vectorcall.md
@@ -0,0 +1,19 @@
+# `abi_vectorcall`
+
+The tracking issue for this feature is: [#124485]
+
+[#124485]: https://github.com/rust-lang/rust/issues/124485
+
+------------------------
+
+Adds support for the Windows `"vectorcall"` ABI, the equivalent of `__vectorcall` in MSVC.
+
+```rust,ignore (only-windows-or-x86-or-x86-64)
+extern "vectorcall" {
+ fn add_f64s(x: f64, y: f64) -> f64;
+}
+
+fn main() {
+ println!("{}", add_f64s(2.0, 4.0));
+}
+```
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index cd88ccd87cf0a..5c9cad2b45d4a 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -6,7 +6,7 @@ use crate::{clip, is_direct_expn_of, sext, unsext};
use rustc_ast::ast::{self, LitFloatType, LitKind};
use rustc_data_structures::sync::Lrc;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp};
+use rustc_hir::{BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp};
use rustc_lexer::tokenize;
use rustc_lint::LateContext;
use rustc_middle::mir::interpret::{alloc_range, Scalar};
@@ -412,7 +412,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
/// Simple constant folding: Insert an expression, get a constant or none.
pub fn expr(&mut self, e: &Expr<'_>) -> Option> {
match e.kind {
- ExprKind::ConstBlock(e) | ExprKind::DropTemps(e) => self.expr(e),
+ ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.lcx.tcx.hir().body(body).value), ExprKind::DropTemps(e) => self.expr(e),
ExprKind::Path(ref qpath) => {
self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| {
let result = mir_to_const(this.lcx, result)?;
@@ -490,7 +490,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
/// leaves the local crate.
pub fn expr_is_empty(&mut self, e: &Expr<'_>) -> Option {
match e.kind {
- ExprKind::ConstBlock(e) | ExprKind::DropTemps(e) => self.expr_is_empty(e),
+ ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr_is_empty(self.lcx.tcx.hir().body(body).value), ExprKind::DropTemps(e) => self.expr_is_empty(e),
ExprKind::Path(ref qpath) => {
if !self
.typeck_results
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index c649c17946843..36634817fc91e 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -295,7 +295,7 @@ impl HirEqInterExpr<'_, '_, '_> {
self.eq_expr(lx, rx) && self.eq_ty(lt, rt)
},
(&ExprKind::Closure(_l), &ExprKind::Closure(_r)) => false,
- (&ExprKind::ConstBlock(lb), &ExprKind::ConstBlock(rb)) => self.eq_expr(lb, rb),
+ (&ExprKind::ConstBlock(lb), &ExprKind::ConstBlock(rb)) => self.eq_body(lb.body, rb.body),
(&ExprKind::Continue(li), &ExprKind::Continue(ri)) => {
both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name)
},
@@ -769,8 +769,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
// closures inherit TypeckResults
self.hash_expr(self.cx.tcx.hir().body(body).value);
},
- ExprKind::ConstBlock(l_id) => {
- self.hash_expr(l_id);
+ ExprKind::ConstBlock(ref l_id) => {
+ self.hash_body(l_id.body);
},
ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => {
self.hash_expr(e);
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
index df14ff396f6cf..8039c0bfa2484 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
@@ -1,35 +1,11 @@
-error: arithmetic operation that can potentially result in unexpected side-effects
- --> tests/ui/arithmetic_side_effects.rs:188:36
- |
-LL | let _ = const { let mut n = 1; n += 1; n };
- | ^^^^^^
- |
- = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`
- = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]`
-
-error: arithmetic operation that can potentially result in unexpected side-effects
- --> tests/ui/arithmetic_side_effects.rs:191:40
- |
-LL | let _ = const { let mut n = 1; n = n + 1; n };
- | ^^^^^
-
-error: arithmetic operation that can potentially result in unexpected side-effects
- --> tests/ui/arithmetic_side_effects.rs:194:40
- |
-LL | let _ = const { let mut n = 1; n = 1 + n; n };
- | ^^^^^
-
-error: arithmetic operation that can potentially result in unexpected side-effects
- --> tests/ui/arithmetic_side_effects.rs:200:59
- |
-LL | let _ = const { let mut n = 1; n = -1; n = -(-1); n = -n; n };
- | ^^
-
error: arithmetic operation that can potentially result in unexpected side-effects
--> tests/ui/arithmetic_side_effects.rs:304:5
|
LL | _n += 1;
| ^^^^^^^
+ |
+ = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]`
error: arithmetic operation that can potentially result in unexpected side-effects
--> tests/ui/arithmetic_side_effects.rs:305:5
@@ -751,5 +727,5 @@ error: arithmetic operation that can potentially result in unexpected side-effec
LL | one.sub_assign(1);
| ^^^^^^^^^^^^^^^^^
-error: aborting due to 125 previous errors
+error: aborting due to 121 previous errors
diff --git a/tests/crashes/119830.rs b/tests/crashes/119830.rs
deleted file mode 100644
index 71becc04e1696..0000000000000
--- a/tests/crashes/119830.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ known-bug: #119830
-#![feature(effects)]
-#![feature(min_specialization)]
-
-trait Specialize {}
-
-trait Foo {}
-
-impl const Foo for T {}
-
-impl const Foo for T where T: const Specialize {}
diff --git a/tests/mir-opt/building/custom/consts.consts.built.after.mir b/tests/mir-opt/building/custom/consts.consts.built.after.mir
index 7b6964849d4b3..a011fadcef116 100644
--- a/tests/mir-opt/building/custom/consts.consts.built.after.mir
+++ b/tests/mir-opt/building/custom/consts.consts.built.after.mir
@@ -10,7 +10,7 @@ fn consts() -> () {
bb0: {
_1 = const 5_u8;
- _2 = const consts::::{constant#1};
+ _2 = const consts::::{constant#0};
_3 = const C;
_4 = const D;
_5 = consts::<10>;
diff --git a/tests/pretty/stmt_expr_attributes.rs b/tests/pretty/stmt_expr_attributes.rs
index f904126821103..5eb7d2fcae36a 100644
--- a/tests/pretty/stmt_expr_attributes.rs
+++ b/tests/pretty/stmt_expr_attributes.rs
@@ -206,7 +206,12 @@ fn _11() {
let _ = ();
()
};
- let const {} = #[rustc_dummy] const {};
+ let const {
+ #![rustc_dummy]
+ } =
+ #[rustc_dummy] const {
+ #![rustc_dummy]
+ };
let mut x = 0;
let _ = (#[rustc_dummy] x) = 15;
let _ = (#[rustc_dummy] x) += 15;
diff --git a/tests/run-make/notify-all-emit-artifacts/lib.rs b/tests/run-make/notify-all-emit-artifacts/lib.rs
new file mode 100644
index 0000000000000..6ed194204b454
--- /dev/null
+++ b/tests/run-make/notify-all-emit-artifacts/lib.rs
@@ -0,0 +1,21 @@
+fn one() -> usize {
+ 1
+}
+
+pub mod a {
+ pub fn two() -> usize {
+ ::one() + ::one()
+ }
+}
+
+pub mod b {
+ pub fn three() -> usize {
+ ::one() + ::a::two()
+ }
+}
+
+#[inline(never)]
+pub fn main() {
+ a::two();
+ b::three();
+}
diff --git a/tests/run-make/notify-all-emit-artifacts/rmake.rs b/tests/run-make/notify-all-emit-artifacts/rmake.rs
new file mode 100644
index 0000000000000..c866d9179f94b
--- /dev/null
+++ b/tests/run-make/notify-all-emit-artifacts/rmake.rs
@@ -0,0 +1,45 @@
+// rust should produce artifact notifications about files it was asked to --emit.
+//
+// It should work in incremental mode both on the first pass where files are generated as well
+// as on subsequent passes where they are taken from the incremental cache
+//
+// See
+extern crate run_make_support;
+
+use run_make_support::{rustc, tmp_dir};
+
+fn main() {
+ let inc_dir = tmp_dir();
+
+ // With single codegen unit files are renamed to match the source file name
+ for _ in 0..=1 {
+ let output = rustc()
+ .input("lib.rs")
+ .emit("obj,asm,llvm-ir,llvm-bc,mir")
+ .codegen_units(1)
+ .json("artifacts")
+ .error_format("json")
+ .incremental(&inc_dir)
+ .run();
+ let stderr = String::from_utf8_lossy(&output.stderr);
+ for file in &["lib.o", "lib.ll", "lib.bc", "lib.s"] {
+ assert!(stderr.contains(file), "No {:?} in {:?}", file, stderr);
+ }
+ }
+
+ // with multiple codegen units files keep codegen unit id part.
+ for _ in 0..=1 {
+ let output = rustc()
+ .input("lib.rs")
+ .emit("obj,asm,llvm-ir,llvm-bc,mir")
+ .codegen_units(2)
+ .json("artifacts")
+ .error_format("json")
+ .incremental(&inc_dir)
+ .run();
+ let stderr = String::from_utf8_lossy(&output.stderr);
+ for file in &["rcgu.o", "rcgu.ll", "rcgu.bc", "rcgu.s"] {
+ assert!(stderr.contains(file), "No {:?} in {:?}", file, stderr);
+ }
+ }
+}
diff --git a/tests/rustdoc-ui/ice-blanket-impl-119792.rs b/tests/rustdoc-ui/ice-blanket-impl-119792.rs
new file mode 100644
index 0000000000000..90f0ea8469b98
--- /dev/null
+++ b/tests/rustdoc-ui/ice-blanket-impl-119792.rs
@@ -0,0 +1,19 @@
+//@ check-pass
+// https://github.com/rust-lang/rust/issues/119792
+
+struct Wrapper(T);
+
+trait Div {}
+trait Mul {
+ type Output;
+}
+
+impl Mul for Wrapper {
+ type Output = ();
+}
+
+impl Div for Wrapper {}
+
+pub trait NumOps {}
+
+impl NumOps for T where T: Mul + Div {}
diff --git a/tests/ui/feature-gates/feature-gate-vectorcall.stderr b/tests/ui/feature-gates/feature-gate-vectorcall.stderr
index df93e8812c1ec..b20e41887b9bf 100644
--- a/tests/ui/feature-gates/feature-gate-vectorcall.stderr
+++ b/tests/ui/feature-gates/feature-gate-vectorcall.stderr
@@ -4,6 +4,7 @@ error[E0658]: vectorcall is experimental and subject to change
LL | extern "vectorcall" fn f() {}
| ^^^^^^^^^^^^
|
+ = note: see issue #124485 for more information
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@@ -13,6 +14,7 @@ error[E0658]: vectorcall is experimental and subject to change
LL | extern "vectorcall" fn m();
| ^^^^^^^^^^^^
|
+ = note: see issue #124485 for more information
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@@ -22,6 +24,7 @@ error[E0658]: vectorcall is experimental and subject to change
LL | extern "vectorcall" fn dm() {}
| ^^^^^^^^^^^^
|
+ = note: see issue #124485 for more information
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@@ -31,6 +34,7 @@ error[E0658]: vectorcall is experimental and subject to change
LL | extern "vectorcall" fn m() {}
| ^^^^^^^^^^^^
|
+ = note: see issue #124485 for more information
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@@ -40,6 +44,7 @@ error[E0658]: vectorcall is experimental and subject to change
LL | extern "vectorcall" fn im() {}
| ^^^^^^^^^^^^
|
+ = note: see issue #124485 for more information
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@@ -49,6 +54,7 @@ error[E0658]: vectorcall is experimental and subject to change
LL | type TA = extern "vectorcall" fn();
| ^^^^^^^^^^^^
|
+ = note: see issue #124485 for more information
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
@@ -58,6 +64,7 @@ error[E0658]: vectorcall is experimental and subject to change
LL | extern "vectorcall" {}
| ^^^^^^^^^^^^
|
+ = note: see issue #124485 for more information
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
diff --git a/tests/ui/inline-const/const_block_pat_liveness.rs b/tests/ui/inline-const/const_block_pat_liveness.rs
new file mode 100644
index 0000000000000..26393a4f65b84
--- /dev/null
+++ b/tests/ui/inline-const/const_block_pat_liveness.rs
@@ -0,0 +1,18 @@
+//! This test used to ICE because const blocks didn't have a body
+//! anymore, making a lot of logic very fragile around handling the
+//! HIR of a const block.
+//! https://github.com/rust-lang/rust/issues/125846
+
+//@ check-pass
+
+#![feature(inline_const_pat)]
+
+fn main() {
+ match 0 {
+ const {
+ let a = 10_usize;
+ *&a
+ }
+ | _ => {}
+ }
+}
diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr
index 48bdaa60823f8..2756ea4013877 100644
--- a/tests/ui/lint/non-local-defs/consts.stderr
+++ b/tests/ui/lint/non-local-defs/consts.stderr
@@ -67,13 +67,18 @@ LL | impl Test {
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
--> $DIR/consts.rs:50:9
|
-LL | fn main() {
- | --------- move the `impl` block outside of this function `main`
-...
-LL | impl Test {
- | ^^^^^----
- | |
- | `Test` is not local
+LL | const {
+ | ___________-
+LL | | impl Test {
+ | | ^^^^^----
+ | | |
+ | | `Test` is not local
+LL | |
+LL | | fn hoo() {}
+... |
+LL | | 1
+LL | | };
+ | |_____- move the `impl` block outside of this inline constant `` and up 2 bodies
|
= note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs
new file mode 100644
index 0000000000000..9778217d462da
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs
@@ -0,0 +1,24 @@
+//@ check-fail
+// Fixes #119830
+
+#![feature(effects)]
+#![feature(min_specialization)]
+#![feature(const_trait_impl)]
+
+trait Specialize {}
+
+trait Foo {}
+
+impl const Foo for T {}
+//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
+//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207]
+
+impl const Foo for T where T: const Specialize {}
+//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
+//~| error: `const` can only be applied to `#[const_trait]` traits
+//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207]
+//~| error: specialization impl does not specialize any associated items
+//~| error: could not resolve generic parameters on overridden impl
+
+fn main() {
+}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr
new file mode 100644
index 0000000000000..d18063f8d3d88
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr
@@ -0,0 +1,69 @@
+error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
+ --> $DIR/spec-effectvar-ice.rs:12:15
+ |
+LL | trait Foo {}
+ | - help: mark `Foo` as const: `#[const_trait]`
+LL |
+LL | impl const Foo for T {}
+ | ^^^
+ |
+ = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+ = note: adding a non-const method body in the future would be a breaking change
+
+error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
+ --> $DIR/spec-effectvar-ice.rs:16:15
+ |
+LL | trait Foo {}
+ | - help: mark `Foo` as const: `#[const_trait]`
+...
+LL | impl const Foo for T where T: const Specialize {}
+ | ^^^
+ |
+ = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
+ = note: adding a non-const method body in the future would be a breaking change
+
+error: `const` can only be applied to `#[const_trait]` traits
+ --> $DIR/spec-effectvar-ice.rs:16:40
+ |
+LL | impl const Foo for T where T: const Specialize {}
+ | ^^^^^^^^^^
+
+error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/spec-effectvar-ice.rs:12:9
+ |
+LL | impl const Foo for T {}
+ | ^^^^^ unconstrained const parameter
+ |
+ = note: expressions using a const parameter must map each value to a distinct output value
+ = note: proving the result of expressions other than the parameter are unique is not supported
+
+error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/spec-effectvar-ice.rs:16:9
+ |
+LL | impl const Foo for T where T: const Specialize {}
+ | ^^^^^ unconstrained const parameter
+ |
+ = note: expressions using a const parameter must map each value to a distinct output value
+ = note: proving the result of expressions other than the parameter are unique is not supported
+
+error: specialization impl does not specialize any associated items
+ --> $DIR/spec-effectvar-ice.rs:16:1
+ |
+LL | impl const Foo for T where T: const Specialize {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: impl is a specialization of this impl
+ --> $DIR/spec-effectvar-ice.rs:12:1
+ |
+LL | impl const Foo for T {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: could not resolve generic parameters on overridden impl
+ --> $DIR/spec-effectvar-ice.rs:16:1
+ |
+LL | impl const Foo for T where T: const Specialize {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout
index 8737063bf3cc7..325bace7b5624 100644
--- a/tests/ui/unpretty/expanded-exhaustive.stdout
+++ b/tests/ui/unpretty/expanded-exhaustive.stdout
@@ -82,8 +82,7 @@ mod expressions {
fn expr_const_block() {
const {};
const { 1 };
- const
- {
+ const {
struct S;
};
}