Skip to content

Rollup of 9 pull requests #125938

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 25 commits into from
Closed
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c8390cd
Show files produced by --emit foo in json artifact notifications
pacak Apr 6, 2024
fc1e52a
Add tracking issue and unstable book page for `"vectorcall"` ABI
beetrees Apr 28, 2024
a126c11
Reorder the TOC so that targets are put under their meta-group
Lokathor May 28, 2024
f646314
make the fact that arm-none-eabi is a group of targets the first thin…
Lokathor May 28, 2024
144adf6
update armv4t docs
Lokathor May 28, 2024
d8704b9
It's spelled "ARM", in all caps.
Lokathor May 28, 2024
bb1f5c3
delete the offending single space.
Lokathor May 28, 2024
94d4040
The modern styling is apparently to use Title Case for the chip/compa…
Lokathor May 31, 2024
c3de4b3
Handle all GVN binops in a single place.
cjgillot Jun 2, 2024
b320ac7
Add a regression test for a former blanket impl synthesis ICE
fmease Jun 3, 2024
f152e2c
Revert "Cache whether a body has inline consts"
oli-obk Jun 3, 2024
c9e50ae
Revert "Create const block DefIds in typeck instead of ast lowering"
oli-obk Jun 3, 2024
0d88bf2
Add regression test
oli-obk Jun 3, 2024
4576027
Remove stray "this"
tbu- Jun 3, 2024
66a1386
Fix ICE caused by ignoring EffectVars in type inference
ajwock Jun 1, 2024
d392c50
Ignore `vec_deque_alloc_error::test_shrink_to_unwind` test on non-unw…
Veykril Jun 3, 2024
16c670c
Rollup merge of #122597 - pacak:master, r=bjorn3
matthiaskrgr Jun 3, 2024
ce4842c
Rollup merge of #124486 - beetrees:vectorcall-tracking-issue, r=ehuss
matthiaskrgr Jun 3, 2024
e68ab49
Rollup merge of #125690 - Lokathor:arm-maintainer-reorg, r=ehuss
matthiaskrgr Jun 3, 2024
183ad51
Rollup merge of #125865 - ajwock:ice_not_fully_resolved, r=fee1-dead
matthiaskrgr Jun 3, 2024
765f55c
Rollup merge of #125893 - cjgillot:gvn-newops, r=oli-obk
matthiaskrgr Jun 3, 2024
0b0dc46
Rollup merge of #125909 - fmease:rustdoc-add-test-synth-blanket-impls…
matthiaskrgr Jun 3, 2024
8e9737a
Rollup merge of #125918 - oli-obk:const_block_ice, r=compiler-errors
matthiaskrgr Jun 3, 2024
7f15094
Rollup merge of #125919 - tbu-:pr_fix_typo, r=lqd
matthiaskrgr Jun 3, 2024
198b58b
Rollup merge of #125927 - ferrocene:lw-alloc-unwind-test, r=pietroalbini
matthiaskrgr Jun 3, 2024
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/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1392,7 +1392,7 @@ pub enum ExprKind {
/// An array (e.g, `[a, b, c, d]`).
Array(ThinVec<P<Expr>>),
/// Allow anonymous constants from an inline `const` block
ConstBlock(P<Expr>),
ConstBlock(AnonConst),
/// A function call
///
/// The first field resolves to the function itself,
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
@@ -1411,7 +1411,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
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);
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
@@ -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));
8 changes: 6 additions & 2 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
@@ -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);
8 changes: 8 additions & 0 deletions compiler/rustc_ast_lowering/src/index.rs
Original file line number Diff line number Diff line change
@@ -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));

8 changes: 1 addition & 7 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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<hir::ItemLocalId, &'hir [Attribute]>,
/// 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 })
5 changes: 2 additions & 3 deletions compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
@@ -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);
23 changes: 23 additions & 0 deletions compiler/rustc_codegen_cranelift/src/driver/aot.rs
Original file line number Diff line number Diff line change
@@ -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
23 changes: 23 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
@@ -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
18 changes: 18 additions & 0 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
@@ -106,6 +106,24 @@ pub struct CompiledModule {
pub llvm_ir: Option<PathBuf>, // --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,
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
@@ -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 {
4 changes: 2 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
@@ -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)),
17 changes: 13 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -907,9 +907,6 @@ pub struct OwnerNodes<'tcx> {
pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
/// Content of local bodies.
pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
/// 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;
13 changes: 12 additions & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
@@ -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,14 +719,22 @@ 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 {
ExprKind::Array(subexpressions) => {
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));
3 changes: 1 addition & 2 deletions compiler/rustc_hir/src/stable_hash_impls.rs
Original file line number Diff line number Diff line change
@@ -93,8 +93,7 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> 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);
}
}
7 changes: 2 additions & 5 deletions compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
@@ -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 {}",
10 changes: 5 additions & 5 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Original file line number Diff line number Diff line change
@@ -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("<const_ty>"),
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
@@ -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()
}
8 changes: 4 additions & 4 deletions compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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(());
}

5 changes: 3 additions & 2 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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()
}

21 changes: 20 additions & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
@@ -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>,
4 changes: 0 additions & 4 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
@@ -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));

4 changes: 4 additions & 0 deletions compiler/rustc_hir_typeck/src/upvar.rs
Original file line number Diff line number Diff line change
@@ -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);
}
_ => {}
}

13 changes: 6 additions & 7 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
@@ -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);
}
_ => {}
}
2 changes: 2 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -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"),
}
}
}
3 changes: 3 additions & 0 deletions compiler/rustc_infer/src/infer/resolve.rs
Original file line number Diff line number Diff line change
@@ -167,6 +167,9 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> 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)
42 changes: 12 additions & 30 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -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<Cow<'hir, Body<'hir>>> {
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<Item = LocalDefId> + '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);
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
@@ -743,7 +743,6 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1,
),
bodies,
has_inline_consts: false,
})));
self.feed_owner_id().hir_attrs(attrs);
}
5 changes: 0 additions & 5 deletions compiler/rustc_middle/src/ty/typeck_results.rs
Original file line number Diff line number Diff line change
@@ -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<ItemLocalId, LocalDefId>,
}

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(),
}
}

7 changes: 5 additions & 2 deletions compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
@@ -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();
6 changes: 3 additions & 3 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
@@ -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));
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/thir/cx/mod.rs
Original file line number Diff line number Diff line change
@@ -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<Item = Param<'tcx>> + 'a {
let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id];

8 changes: 5 additions & 3 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions compiler/rustc_mir_transform/src/dump_mir.rs
Original file line number Diff line number Diff line change
@@ -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(())
70 changes: 40 additions & 30 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
@@ -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 {
10 changes: 0 additions & 10 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
@@ -222,16 +222,6 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
// 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> {
13 changes: 8 additions & 5 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -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).
10 changes: 5 additions & 5 deletions compiler/rustc_passes/src/check_const.rs
Original file line number Diff line number Diff line change
@@ -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;
}

_ => {}
}
21 changes: 11 additions & 10 deletions compiler/rustc_passes/src/dead.rs
Original file line number Diff line number Diff line change
@@ -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(
8 changes: 1 addition & 7 deletions compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
@@ -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),
7 changes: 4 additions & 3 deletions compiler/rustc_passes/src/loops.rs
Original file line number Diff line number Diff line change
@@ -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),
}
}
10 changes: 10 additions & 0 deletions compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
@@ -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,
};

6 changes: 2 additions & 4 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
@@ -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));
1 change: 1 addition & 0 deletions library/alloc/tests/vec_deque_alloc_error.rs
Original file line number Diff line number Diff line change
@@ -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
3 changes: 1 addition & 2 deletions library/std/src/sys/pal/unix/fs.rs
Original file line number Diff line number Diff line change
@@ -1910,8 +1910,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
// 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);
}
}
18 changes: 9 additions & 9 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -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)
8 changes: 7 additions & 1 deletion src/doc/rustc/src/json.md
Original file line number Diff line number Diff line change
@@ -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"
}
28 changes: 17 additions & 11 deletions src/doc/rustc/src/platform-support/arm-none-eabi.md
Original file line number Diff line number Diff line change
@@ -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
21 changes: 9 additions & 12 deletions src/doc/rustc/src/platform-support/armv4t-none-eabi.md
Original file line number Diff line number Diff line change
@@ -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.
19 changes: 19 additions & 0 deletions src/doc/unstable-book/src/language-features/abi-vectorcall.md
Original file line number Diff line number Diff line change
@@ -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));
}
```
6 changes: 3 additions & 3 deletions src/tools/clippy/clippy_utils/src/consts.rs
Original file line number Diff line number Diff line change
@@ -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<Constant<'tcx>> {
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<bool> {
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
6 changes: 3 additions & 3 deletions src/tools/clippy/clippy_utils/src/hir_utils.rs
Original file line number Diff line number Diff line change
@@ -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);
32 changes: 4 additions & 28 deletions src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
Original file line number Diff line number Diff line change
@@ -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

11 changes: 0 additions & 11 deletions tests/crashes/119830.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ fn consts() -> () {

bb0: {
_1 = const 5_u8;
_2 = const consts::<C>::{constant#1};
_2 = const consts::<C>::{constant#0};
_3 = const C;
_4 = const D;
_5 = consts::<10>;
7 changes: 6 additions & 1 deletion tests/pretty/stmt_expr_attributes.rs
Original file line number Diff line number Diff line change
@@ -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;
21 changes: 21 additions & 0 deletions tests/run-make/notify-all-emit-artifacts/lib.rs
Original file line number Diff line number Diff line change
@@ -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();
}
45 changes: 45 additions & 0 deletions tests/run-make/notify-all-emit-artifacts/rmake.rs
Original file line number Diff line number Diff line change
@@ -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 <https://internals.rust-lang.org/t/easier-access-to-files-generated-by-emit-foo/20477>
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);
}
}
}
19 changes: 19 additions & 0 deletions tests/rustdoc-ui/ice-blanket-impl-119792.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ check-pass
// https://github.com/rust-lang/rust/issues/119792

struct Wrapper<T>(T);

trait Div<Rhs> {}
trait Mul<Rhs> {
type Output;
}

impl<T> Mul<T> for Wrapper<T> {
type Output = ();
}

impl<T> Div<Self> for Wrapper<T> {}

pub trait NumOps<Rhs> {}

impl<T, Rhs> NumOps<Rhs> for T where T: Mul<Rhs, Output = ()> + Div<Rhs> {}
7 changes: 7 additions & 0 deletions tests/ui/feature-gates/feature-gate-vectorcall.stderr
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ error[E0658]: vectorcall is experimental and subject to change
LL | extern "vectorcall" fn f() {}
| ^^^^^^^^^^^^
|
= note: see issue #124485 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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

18 changes: 18 additions & 0 deletions tests/ui/inline-const/const_block_pat_liveness.rs
Original file line number Diff line number Diff line change
@@ -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
}
| _ => {}
}
}
19 changes: 12 additions & 7 deletions tests/ui/lint/non-local-defs/consts.stderr
Original file line number Diff line number Diff line change
@@ -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 `<unnameable>` 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 <https://github.com/rust-lang/rust/issues/120363>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ check-fail
// Fixes #119830

#![feature(effects)]
#![feature(min_specialization)]
#![feature(const_trait_impl)]

trait Specialize {}

trait Foo {}

impl<T> 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<T> 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() {
}
Original file line number Diff line number Diff line change
@@ -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<T> 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<T> 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<T> 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<T> 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<T> 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<T> 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<T> const Foo for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^

error: could not resolve generic parameters on overridden impl
--> $DIR/spec-effectvar-ice.rs:16:1
|
LL | impl<T> 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`.
3 changes: 1 addition & 2 deletions tests/ui/unpretty/expanded-exhaustive.stdout
Original file line number Diff line number Diff line change
@@ -82,8 +82,7 @@ mod expressions {
fn expr_const_block() {
const {};
const { 1 };
const
{
const {
struct S;
};
}