diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 9b6bfaadef05a..fb9d71b52a8a6 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2890,6 +2890,20 @@ pub struct Fn {
pub body: Option
>,
}
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct StaticItem {
+ pub ty: P,
+ pub mutability: Mutability,
+ pub expr: Option>,
+}
+
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct ConstItem {
+ pub defaultness: Defaultness,
+ pub ty: P,
+ pub expr: Option>,
+}
+
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum ItemKind {
/// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
@@ -2903,11 +2917,11 @@ pub enum ItemKind {
/// A static item (`static`).
///
/// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
- Static(P, Mutability, Option>),
+ Static(Box),
/// A constant item (`const`).
///
/// E.g., `const FOO: i32 = 42;`.
- Const(Defaultness, P, Option>),
+ Const(Box),
/// A function declaration (`fn`).
///
/// E.g., `fn foo(bar: usize) -> usize { .. }`.
@@ -3023,7 +3037,7 @@ pub type AssocItem = Item;
pub enum AssocItemKind {
/// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`.
/// If `def` is parsed, then the constant is provided, and otherwise required.
- Const(Defaultness, P, Option>),
+ Const(Box),
/// An associated function.
Fn(Box),
/// An associated type.
@@ -3035,7 +3049,7 @@ pub enum AssocItemKind {
impl AssocItemKind {
pub fn defaultness(&self) -> Defaultness {
match *self {
- Self::Const(defaultness, ..)
+ Self::Const(box ConstItem { defaultness, .. })
| Self::Fn(box Fn { defaultness, .. })
| Self::Type(box TyAlias { defaultness, .. }) => defaultness,
Self::MacCall(..) => Defaultness::Final,
@@ -3046,7 +3060,7 @@ impl AssocItemKind {
impl From for ItemKind {
fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
match assoc_item_kind {
- AssocItemKind::Const(a, b, c) => ItemKind::Const(a, b, c),
+ AssocItemKind::Const(item) => ItemKind::Const(item),
AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
@@ -3059,7 +3073,7 @@ impl TryFrom for AssocItemKind {
fn try_from(item_kind: ItemKind) -> Result {
Ok(match item_kind {
- ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c),
+ ItemKind::Const(item) => AssocItemKind::Const(item),
ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
@@ -3084,7 +3098,9 @@ pub enum ForeignItemKind {
impl From for ItemKind {
fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
match foreign_item_kind {
- ForeignItemKind::Static(a, b, c) => ItemKind::Static(a, b, c),
+ ForeignItemKind::Static(a, b, c) => {
+ ItemKind::Static(StaticItem { ty: a, mutability: b, expr: c }.into())
+ }
ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
@@ -3097,7 +3113,9 @@ impl TryFrom for ForeignItemKind {
fn try_from(item_kind: ItemKind) -> Result {
Ok(match item_kind {
- ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c),
+ ItemKind::Static(box StaticItem { ty: a, mutability: b, expr: c }) => {
+ ForeignItemKind::Static(a, b, c)
+ }
ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
@@ -3114,8 +3132,8 @@ mod size_asserts {
use super::*;
use rustc_data_structures::static_assert_size;
// tidy-alphabetical-start
- static_assert_size!(AssocItem, 104);
- static_assert_size!(AssocItemKind, 32);
+ static_assert_size!(AssocItem, 88);
+ static_assert_size!(AssocItemKind, 16);
static_assert_size!(Attribute, 32);
static_assert_size!(Block, 32);
static_assert_size!(Expr, 72);
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 514978f5569a7..2424073ae53ad 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -7,10 +7,10 @@
//! a `MutVisitor` renaming item names in a module will miss all of those
//! that are created by the expansion of a macro.
-use crate::ast::*;
use crate::ptr::P;
use crate::token::{self, Token};
use crate::tokenstream::*;
+use crate::{ast::*, StaticItem};
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_data_structures::sync::Lrc;
@@ -1030,14 +1030,12 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) {
match kind {
ItemKind::ExternCrate(_orig_name) => {}
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
- ItemKind::Static(ty, _, expr) => {
+ ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
}
- ItemKind::Const(defaultness, ty, expr) => {
- visit_defaultness(defaultness, vis);
- vis.visit_ty(ty);
- visit_opt(expr, |expr| vis.visit_expr(expr));
+ ItemKind::Const(item) => {
+ visit_const_item(item, vis);
}
ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
visit_defaultness(defaultness, vis);
@@ -1120,10 +1118,8 @@ pub fn noop_flat_map_assoc_item(
visitor.visit_vis(vis);
visit_attrs(attrs, visitor);
match kind {
- AssocItemKind::Const(defaultness, ty, expr) => {
- visit_defaultness(defaultness, visitor);
- visitor.visit_ty(ty);
- visit_opt(expr, |expr| visitor.visit_expr(expr));
+ AssocItemKind::Const(item) => {
+ visit_const_item(item, visitor);
}
AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
visit_defaultness(defaultness, visitor);
@@ -1153,6 +1149,15 @@ pub fn noop_flat_map_assoc_item(
smallvec![item]
}
+fn visit_const_item(
+ ConstItem { defaultness, ty, expr }: &mut ConstItem,
+ visitor: &mut T,
+) {
+ visit_defaultness(defaultness, visitor);
+ visitor.visit_ty(ty);
+ visit_opt(expr, |expr| visitor.visit_expr(expr));
+}
+
pub fn noop_visit_fn_header(header: &mut FnHeader, vis: &mut T) {
let FnHeader { unsafety, asyncness, constness, ext: _ } = header;
visit_constness(constness, vis);
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index e5a0ad1f1e481..3b08467fde2bf 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -13,7 +13,7 @@
//! instance, a walker looking for item names in a module will miss all of
//! those that are created by the expansion of a macro.
-use crate::ast::*;
+use crate::{ast::*, StaticItem};
use rustc_span::symbol::Ident;
use rustc_span::Span;
@@ -305,8 +305,9 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
match &item.kind {
ItemKind::ExternCrate(_) => {}
ItemKind::Use(use_tree) => visitor.visit_use_tree(use_tree, item.id, false),
- ItemKind::Static(typ, _, expr) | ItemKind::Const(_, typ, expr) => {
- visitor.visit_ty(typ);
+ ItemKind::Static(box StaticItem { ty, mutability: _, expr })
+ | ItemKind::Const(box ConstItem { ty, expr, .. }) => {
+ visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr);
}
ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
@@ -674,7 +675,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
visitor.visit_ident(ident);
walk_list!(visitor, visit_attribute, attrs);
match kind {
- AssocItemKind::Const(_, ty, expr) => {
+ AssocItemKind::Const(box ConstItem { ty, expr, .. }) => {
visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr);
}
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 2efffbb6dc5e3..f89e254a2f54d 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -229,12 +229,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
}
- ItemKind::Static(t, m, e) => {
+ ItemKind::Static(box ast::StaticItem { ty: t, mutability: m, expr: e }) => {
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
hir::ItemKind::Static(ty, *m, body_id)
}
- ItemKind::Const(_, t, e) => {
- let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
+ ItemKind::Const(box ast::ConstItem { ty, expr, .. }) => {
+ let (ty, body_id) = self.lower_const_item(ty, span, expr.as_deref());
hir::ItemKind::Const(ty, body_id)
}
ItemKind::Fn(box Fn {
@@ -708,10 +708,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
let trait_item_def_id = hir_id.expect_owner();
let (generics, kind, has_default) = match &i.kind {
- AssocItemKind::Const(_, ty, default) => {
+ AssocItemKind::Const(box ConstItem { ty, expr, .. }) => {
let ty =
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
- let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
+ let body = expr.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
}
AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => {
@@ -809,7 +809,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_attrs(hir_id, &i.attrs);
let (generics, kind) = match &i.kind {
- AssocItemKind::Const(_, ty, expr) => {
+ AssocItemKind::Const(box ConstItem { ty, expr, .. }) => {
let ty =
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
(
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 44b6c77fc4195..236ebd04ae88d 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -9,8 +9,8 @@
use itertools::{Either, Itertools};
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
-use rustc_ast::walk_list;
use rustc_ast::*;
+use rustc_ast::{walk_list, StaticItem};
use rustc_ast_pretty::pprust::{self, State};
use rustc_data_structures::fx::FxIndexMap;
use rustc_macros::Subdiagnostic;
@@ -983,14 +983,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.err_handler().emit_err(errors::FieldlessUnion { span: item.span });
}
}
- ItemKind::Const(def, .., None) => {
- self.check_defaultness(item.span, *def);
+ ItemKind::Const(box ConstItem { defaultness, expr: None, .. }) => {
+ self.check_defaultness(item.span, *defaultness);
self.session.emit_err(errors::ConstWithoutBody {
span: item.span,
replace_span: self.ending_semi_or_hi(item.span),
});
}
- ItemKind::Static(.., None) => {
+ ItemKind::Static(box StaticItem { expr: None, .. }) => {
self.session.emit_err(errors::StaticWithoutBody {
span: item.span,
replace_span: self.ending_semi_or_hi(item.span),
@@ -1259,13 +1259,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if ctxt == AssocCtxt::Impl {
match &item.kind {
- AssocItemKind::Const(_, _, body) => {
- if body.is_none() {
- self.session.emit_err(errors::AssocConstWithoutBody {
- span: item.span,
- replace_span: self.ending_semi_or_hi(item.span),
- });
- }
+ AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
+ self.session.emit_err(errors::AssocConstWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
}
AssocItemKind::Fn(box Fn { body, .. }) => {
if body.is_none() {
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index de94c1bc47794..b3923b651eb3b 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -485,17 +485,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
if let Some(args) = constraint.gen_args.as_ref()
&& matches!(
args,
- ast::GenericArgs::ReturnTypeNotation(..) | ast::GenericArgs::Parenthesized(..)
+ ast::GenericArgs::ReturnTypeNotation(..)
)
{
- // RTN is gated elsewhere, and parenthesized args will turn into
- // another error.
- if matches!(args, ast::GenericArgs::Parenthesized(..)) {
- self.sess.delay_span_bug(
- constraint.span,
- "should have emitted a parenthesized generics error",
- );
- }
+ // RTN is gated below with a `gate_all`.
} else {
gate_feature_post!(
&self,
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index bf2c73a66a2cb..c465f8c948a80 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -2,6 +2,7 @@ use crate::pp::Breaks::Inconsistent;
use crate::pprust::state::delimited::IterDelimited;
use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
+use ast::StaticItem;
use rustc_ast as ast;
use rustc_ast::GenericBound;
use rustc_ast::ModKind;
@@ -156,7 +157,7 @@ impl<'a> State<'a> {
self.print_use_tree(tree);
self.word(";");
}
- ast::ItemKind::Static(ty, mutbl, body) => {
+ ast::ItemKind::Static(box StaticItem { ty, mutability: mutbl, expr: body }) => {
let def = ast::Defaultness::Final;
self.print_item_const(
item.ident,
@@ -167,8 +168,15 @@ impl<'a> State<'a> {
def,
);
}
- ast::ItemKind::Const(def, ty, body) => {
- self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, *def);
+ ast::ItemKind::Const(box ast::ConstItem { defaultness, ty, expr }) => {
+ self.print_item_const(
+ item.ident,
+ None,
+ ty,
+ expr.as_deref(),
+ &item.vis,
+ *defaultness,
+ );
}
ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
self.print_fn_full(
@@ -507,8 +515,8 @@ impl<'a> State<'a> {
ast::AssocItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
}
- ast::AssocItemKind::Const(def, ty, body) => {
- self.print_item_const(ident, None, ty, body.as_deref(), vis, *def);
+ ast::AssocItemKind::Const(box ast::ConstItem { defaultness, ty, expr }) => {
+ self.print_item_const(ident, None, ty, expr.as_deref(), vis, *defaultness);
}
ast::AssocItemKind::Type(box ast::TyAlias {
defaultness,
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
index 8023ef60d2052..2c387edfef073 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs
@@ -63,7 +63,7 @@ impl LocalUseMap {
elements: &RegionValueElements,
body: &Body<'_>,
) -> Self {
- let nones = IndexVec::from_elem_n(None, body.local_decls.len());
+ let nones = IndexVec::from_elem(None, &body.local_decls);
let mut local_use_map = LocalUseMap {
first_def_at: nones.clone(),
first_use_at: nones.clone(),
@@ -76,7 +76,7 @@ impl LocalUseMap {
}
let mut locals_with_use_data: IndexVec =
- IndexVec::from_elem_n(false, body.local_decls.len());
+ IndexVec::from_elem(false, &body.local_decls);
live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
LocalUseMapBuild { local_use_map: &mut local_use_map, elements, locals_with_use_data }
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 41b51bae73645..866cc5adbf3b1 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -25,12 +25,12 @@ pub fn expand(
// FIXME - if we get deref patterns, use them to reduce duplication here
let (item, is_stmt, ty_span) =
if let Annotatable::Item(item) = &item
- && let ItemKind::Static(ty, ..) = &item.kind
+ && let ItemKind::Static(box ast::StaticItem { ty, ..}) = &item.kind
{
(item, false, ecx.with_def_site_ctxt(ty.span))
} else if let Annotatable::Stmt(stmt) = &item
&& let StmtKind::Item(item) = &stmt.kind
- && let ItemKind::Static(ty, ..) = &item.kind
+ && let ItemKind::Static(box ast::StaticItem { ty, ..}) = &item.kind
{
(item, true, ecx.with_def_site_ctxt(ty.span))
} else {
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index 44b9c4718a75f..a76ed4ee6cee3 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -254,25 +254,27 @@ pub fn expand_test_or_bench(
let location_info = get_location_info(cx, &item);
- let mut test_const = cx.item(
- sp,
- Ident::new(item.ident.name, sp),
- thin_vec![
- // #[cfg(test)]
- cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
- // #[rustc_test_marker = "test_case_sort_key"]
- cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp),
- ],
- // const $ident: test::TestDescAndFn =
- ast::ItemKind::Const(
- ast::Defaultness::Final,
- cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
- // test::TestDescAndFn {
- Some(
- cx.expr_struct(
- sp,
- test_path("TestDescAndFn"),
- thin_vec![
+ let mut test_const =
+ cx.item(
+ sp,
+ Ident::new(item.ident.name, sp),
+ thin_vec![
+ // #[cfg(test)]
+ cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
+ // #[rustc_test_marker = "test_case_sort_key"]
+ cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp),
+ ],
+ // const $ident: test::TestDescAndFn =
+ ast::ItemKind::Const(
+ ast::ConstItem {
+ defaultness: ast::Defaultness::Final,
+ ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
+ // test::TestDescAndFn {
+ expr: Some(
+ cx.expr_struct(
+ sp,
+ test_path("TestDescAndFn"),
+ thin_vec![
// desc: test::TestDesc {
field(
"desc",
@@ -359,10 +361,12 @@ pub fn expand_test_or_bench(
// testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
field("testfn", test_fn), // }
],
- ), // }
+ ), // }
+ ),
+ }
+ .into(),
),
- ),
- );
+ );
test_const = test_const.map(|mut tc| {
tc.vis.kind = ast::VisibilityKind::Public;
tc
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index ff25d1e38236d..280f0207116f3 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -165,11 +165,15 @@ fn calculate_debuginfo_offset<
mir::ProjectionElem::Downcast(_, variant) => {
place = place.downcast(bx, variant);
}
- _ => span_bug!(
- var.source_info.span,
- "unsupported var debuginfo place `{:?}`",
- mir::Place { local, projection: var.projection },
- ),
+ _ => {
+ // Sanity check for `can_use_in_debuginfo`.
+ debug_assert!(!elem.can_use_in_debuginfo());
+ span_bug!(
+ var.source_info.span,
+ "unsupported var debuginfo place `{:?}`",
+ mir::Place { local, projection: var.projection },
+ )
+ }
}
}
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 8d5192bca67e5..5310ef0bb3ed0 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -612,14 +612,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
span: Option,
layout: Option>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
- // FIXME(const_prop): normalization needed b/c const prop lint in
- // `mir_drops_elaborated_and_const_checked`, which happens before
- // optimized MIR. Only after optimizing the MIR can we guarantee
- // that the `RevealAll` pass has happened and that the body's consts
- // are normalized, so any call to resolve before that needs to be
- // manually normalized.
- let val = self.tcx.normalize_erasing_regions(self.param_env, *val);
- match val {
+ match *val {
mir::ConstantKind::Ty(ct) => {
let ty = ct.ty();
let valtree = self.eval_ty_constant(ct, span)?;
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 558253f727bcc..e798c9d236e1a 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -5,13 +5,12 @@ use rustc_index::bit_set::BitSet;
use rustc_index::vec::IndexVec;
use rustc_infer::traits::Reveal;
use rustc_middle::mir::interpret::Scalar;
-use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
-use rustc_middle::mir::visit::{PlaceContext, Visitor};
+use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
use rustc_middle::mir::{
traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location,
MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem,
RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
- TerminatorKind, UnOp, START_BLOCK,
+ TerminatorKind, UnOp, VarDebugInfo, VarDebugInfoContents, START_BLOCK,
};
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
use rustc_mir_dataflow::impls::MaybeStorageLive;
@@ -419,13 +418,49 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
self.super_projection_elem(local, proj_base, elem, context, location);
}
+ fn visit_var_debug_info(&mut self, debuginfo: &VarDebugInfo<'tcx>) {
+ let check_place = |place: Place<'_>| {
+ if place.projection.iter().any(|p| !p.can_use_in_debuginfo()) {
+ self.fail(
+ START_BLOCK.start_location(),
+ format!("illegal place {:?} in debuginfo for {:?}", place, debuginfo.name),
+ );
+ }
+ };
+ match debuginfo.value {
+ VarDebugInfoContents::Const(_) => {}
+ VarDebugInfoContents::Place(place) => check_place(place),
+ VarDebugInfoContents::Composite { ty, ref fragments } => {
+ for f in fragments {
+ check_place(f.contents);
+ if ty.is_union() || ty.is_enum() {
+ self.fail(
+ START_BLOCK.start_location(),
+ format!("invalid type {:?} for composite debuginfo", ty),
+ );
+ }
+ if f.projection.iter().any(|p| !matches!(p, PlaceElem::Field(..))) {
+ self.fail(
+ START_BLOCK.start_location(),
+ format!(
+ "illegal projection {:?} in debuginfo for {:?}",
+ f.projection, debuginfo.name
+ ),
+ );
+ }
+ }
+ }
+ }
+ self.super_var_debug_info(debuginfo);
+ }
+
fn visit_place(&mut self, place: &Place<'tcx>, cntxt: PlaceContext, location: Location) {
// Set off any `bug!`s in the type computation code
let _ = place.ty(&self.body.local_decls, self.tcx);
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial)
&& place.projection.len() > 1
- && cntxt != PlaceContext::NonUse(VarDebugInfo)
+ && cntxt != PlaceContext::NonUse(NonUseContext::VarDebugInfo)
&& place.projection[1..].contains(&ProjectionElem::Deref)
{
self.fail(location, format!("{:?}, has deref at the wrong place", place));
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 8a16143311b8f..264f30fb10a12 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -620,10 +620,15 @@ impl<'a> ExtCtxt<'a> {
span: Span,
name: Ident,
ty: P,
- mutbl: ast::Mutability,
+ mutability: ast::Mutability,
expr: P,
) -> P {
- self.item(span, name, AttrVec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr)))
+ self.item(
+ span,
+ name,
+ AttrVec::new(),
+ ast::ItemKind::Static(ast::StaticItem { ty, mutability, expr: Some(expr) }.into()),
+ )
}
pub fn item_const(
@@ -633,8 +638,13 @@ impl<'a> ExtCtxt<'a> {
ty: P,
expr: P,
) -> P {
- let def = ast::Defaultness::Final;
- self.item(span, name, AttrVec::new(), ast::ItemKind::Const(def, ty, Some(expr)))
+ let defaultness = ast::Defaultness::Final;
+ self.item(
+ span,
+ name,
+ AttrVec::new(),
+ ast::ItemKind::Const(ast::ConstItem { defaultness, ty, expr: Some(expr) }.into()),
+ )
}
// Builds `#[name]`.
diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs
index 5945de2302a56..16cf9ae5cfc28 100644
--- a/compiler/rustc_index/src/vec.rs
+++ b/compiler/rustc_index/src/vec.rs
@@ -129,6 +129,17 @@ impl IndexVec {
IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData }
}
+ /// Creates a new vector with a copy of `elem` for each index in `universe`.
+ ///
+ /// Thus `IndexVec::from_elem(elem, &universe)` is equivalent to
+ /// `IndexVec::::from_elem_n(elem, universe.len())`. That can help
+ /// type inference as it ensures that the resulting vector uses the same
+ /// index type as `universe`, rather than something potentially surprising.
+ ///
+ /// For example, if you want to store data for each local in a MIR body,
+ /// using `let mut uses = IndexVec::from_elem(vec![], &body.local_decls);`
+ /// ensures that `uses` is an `IndexVec`, and thus can give
+ /// better error messages later if one accidentally mismatches indices.
#[inline]
pub fn from_elem(elem: T, universe: &IndexSlice) -> Self
where
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 9e2bdb7f510b3..f298b95ca35b1 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -203,7 +203,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
// Tracks the `VarSubVar` constraints generated for each region vid. We
// later use this to expand across vids.
- let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len());
+ let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values);
// Tracks the changed region vids.
let mut changes = Vec::new();
for constraint in self.data.constraints.keys() {
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 42e59f92840e0..ad328006051f1 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -805,7 +805,9 @@ trait UnusedDelimLint {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
use ast::ItemKind::*;
- if let Const(.., Some(expr)) | Static(.., Some(expr)) = &item.kind {
+ if let Const(box ast::ConstItem { expr: Some(expr), .. })
+ | Static(box ast::StaticItem { expr: Some(expr), .. }) = &item.kind
+ {
self.check_unused_delims_expr(
cx,
expr,
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 44fd8478be9b5..b88a315cec132 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1036,8 +1036,7 @@ impl<'tcx> LocalDecl<'tcx> {
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub enum VarDebugInfoContents<'tcx> {
- /// NOTE(eddyb) There's an unenforced invariant that this `Place` is
- /// based on a `Local`, not a `Static`, and contains no indexing.
+ /// This `Place` only contains projection which satisfy `can_use_in_debuginfo`.
Place(Place<'tcx>),
Const(Constant<'tcx>),
/// The user variable's data is split across several fragments,
@@ -1047,6 +1046,7 @@ pub enum VarDebugInfoContents<'tcx> {
/// the underlying debuginfo feature this relies on.
Composite {
/// Type of the original user variable.
+ /// This cannot contain a union or an enum.
ty: Ty<'tcx>,
/// All the parts of the original user variable, which ended
/// up in disjoint places, due to optimizations.
@@ -1075,17 +1075,16 @@ pub struct VarDebugInfoFragment<'tcx> {
/// Where in the composite user variable this fragment is,
/// represented as a "projection" into the composite variable.
/// At lower levels, this corresponds to a byte/bit range.
- // NOTE(eddyb) there's an unenforced invariant that this contains
- // only `Field`s, and not into `enum` variants or `union`s.
- // FIXME(eddyb) support this for `enum`s by either using DWARF's
+ ///
+ /// This can only contain `PlaceElem::Field`.
+ // FIXME support this for `enum`s by either using DWARF's
// more advanced control-flow features (unsupported by LLVM?)
// to match on the discriminant, or by using custom type debuginfo
// with non-overlapping variants for the composite variable.
pub projection: Vec>,
/// Where the data for this fragment can be found.
- // NOTE(eddyb) There's an unenforced invariant that this `Place` is
- // contains no indexing (with a non-constant index).
+ /// This `Place` only contains projection which satisfy `can_use_in_debuginfo`.
pub contents: Place<'tcx>,
}
@@ -1538,6 +1537,17 @@ impl ProjectionElem {
pub fn is_field_to(&self, f: FieldIdx) -> bool {
matches!(*self, Self::Field(x, _) if x == f)
}
+
+ /// Returns `true` if this is accepted inside `VarDebugInfoContents::Place`.
+ pub fn can_use_in_debuginfo(&self) -> bool {
+ match self {
+ Self::Deref | Self::Downcast(_, _) | Self::Field(_, _) => true,
+ Self::ConstantIndex { .. }
+ | Self::Index(_)
+ | Self::OpaqueCast(_)
+ | Self::Subslice { .. } => false,
+ }
+ }
}
/// Alias for projections as they appear in `UserTypeProjection`, where we
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index 578cd82aa4c2a..7c59879a187fe 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -193,9 +193,9 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
let arg = self.param_env.and(arg);
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!(
- "Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
- arg.value
- ))
+ "Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
+ arg.value
+ ))
}
}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index e619e095496bc..29f7cae3d3fec 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -1154,8 +1154,9 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
fn wildcards_from_tys(
cx: &MatchCheckCtxt<'p, 'tcx>,
tys: impl IntoIterator- >,
+ span: Span,
) -> Self {
- Fields::from_iter(cx, tys.into_iter().map(DeconstructedPat::wildcard))
+ Fields::from_iter(cx, tys.into_iter().map(|ty| DeconstructedPat::wildcard(ty, span)))
}
// In the cases of either a `#[non_exhaustive]` field list or a non-public field, we hide
@@ -1191,18 +1192,18 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
pub(super) fn wildcards(pcx: &PatCtxt<'_, 'p, 'tcx>, constructor: &Constructor<'tcx>) -> Self {
let ret = match constructor {
Single | Variant(_) => match pcx.ty.kind() {
- ty::Tuple(fs) => Fields::wildcards_from_tys(pcx.cx, fs.iter()),
- ty::Ref(_, rty, _) => Fields::wildcards_from_tys(pcx.cx, once(*rty)),
+ ty::Tuple(fs) => Fields::wildcards_from_tys(pcx.cx, fs.iter(), pcx.span),
+ ty::Ref(_, rty, _) => Fields::wildcards_from_tys(pcx.cx, once(*rty), pcx.span),
ty::Adt(adt, substs) => {
if adt.is_box() {
// The only legal patterns of type `Box` (outside `std`) are `_` and box
// patterns. If we're here we can assume this is a box pattern.
- Fields::wildcards_from_tys(pcx.cx, once(substs.type_at(0)))
+ Fields::wildcards_from_tys(pcx.cx, once(substs.type_at(0)), pcx.span)
} else {
let variant = &adt.variant(constructor.variant_index_for_adt(*adt));
let tys = Fields::list_variant_nonhidden_fields(pcx.cx, pcx.ty, variant)
.map(|(_, ty)| ty);
- Fields::wildcards_from_tys(pcx.cx, tys)
+ Fields::wildcards_from_tys(pcx.cx, tys, pcx.span)
}
}
_ => bug!("Unexpected type for `Single` constructor: {:?}", pcx),
@@ -1210,7 +1211,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
Slice(slice) => match *pcx.ty.kind() {
ty::Slice(ty) | ty::Array(ty, _) => {
let arity = slice.arity();
- Fields::wildcards_from_tys(pcx.cx, (0..arity).map(|_| ty))
+ Fields::wildcards_from_tys(pcx.cx, (0..arity).map(|_| ty), pcx.span)
}
_ => bug!("bad slice pattern {:?} {:?}", constructor, pcx),
},
@@ -1251,8 +1252,8 @@ pub(crate) struct DeconstructedPat<'p, 'tcx> {
}
impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
- pub(super) fn wildcard(ty: Ty<'tcx>) -> Self {
- Self::new(Wildcard, Fields::empty(), ty, DUMMY_SP)
+ pub(super) fn wildcard(ty: Ty<'tcx>, span: Span) -> Self {
+ Self::new(Wildcard, Fields::empty(), ty, span)
}
pub(super) fn new(
@@ -1269,7 +1270,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
/// `Some(_)`.
pub(super) fn wild_from_ctor(pcx: &PatCtxt<'_, 'p, 'tcx>, ctor: Constructor<'tcx>) -> Self {
let fields = Fields::wildcards(pcx, &ctor);
- DeconstructedPat::new(ctor, fields, pcx.ty, DUMMY_SP)
+ DeconstructedPat::new(ctor, fields, pcx.ty, pcx.span)
}
/// Clone this value. This method emphasizes that cloning loses reachability information and
@@ -1298,7 +1299,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
ty::Tuple(fs) => {
ctor = Single;
let mut wilds: SmallVec<[_; 2]> =
- fs.iter().map(DeconstructedPat::wildcard).collect();
+ fs.iter().map(|ty| DeconstructedPat::wildcard(ty, pat.span)).collect();
for pat in subpatterns {
wilds[pat.field.index()] = mkpat(&pat.pattern);
}
@@ -1317,11 +1318,11 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
// normally or through box-patterns. We'll have to figure out a proper
// solution when we introduce generalized deref patterns. Also need to
// prevent mixing of those two options.
- let pat = subpatterns.into_iter().find(|pat| pat.field.index() == 0);
- let pat = if let Some(pat) = pat {
+ let pattern = subpatterns.into_iter().find(|pat| pat.field.index() == 0);
+ let pat = if let Some(pat) = pattern {
mkpat(&pat.pattern)
} else {
- DeconstructedPat::wildcard(substs.type_at(0))
+ DeconstructedPat::wildcard(substs.type_at(0), pat.span)
};
ctor = Single;
fields = Fields::singleton(cx, pat);
@@ -1343,7 +1344,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
ty
});
let mut wilds: SmallVec<[_; 2]> =
- tys.map(DeconstructedPat::wildcard).collect();
+ tys.map(|ty| DeconstructedPat::wildcard(ty, pat.span)).collect();
for pat in subpatterns {
if let Some(i) = field_id_to_id[pat.field.index()] {
wilds[i] = mkpat(&pat.pattern);
@@ -1566,8 +1567,10 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
};
let prefix = &self.fields.fields[..prefix];
let suffix = &self.fields.fields[self_slice.arity() - suffix..];
- let wildcard: &_ =
- pcx.cx.pattern_arena.alloc(DeconstructedPat::wildcard(inner_ty));
+ let wildcard: &_ = pcx
+ .cx
+ .pattern_arena
+ .alloc(DeconstructedPat::wildcard(inner_ty, pcx.span));
let extra_wildcards = other_slice.arity() - self_slice.arity();
let extra_wildcards = (0..extra_wildcards).map(|_| wildcard);
prefix.iter().chain(extra_wildcards).chain(suffix).collect()
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 9edd7967e7a4a..a324c3a622806 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -604,7 +604,7 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
let new_patterns = if pcx.is_non_exhaustive {
// Here we don't want the user to try to list all variants, we want them to add
// a wildcard, so we only suggest that.
- vec![DeconstructedPat::wildcard(pcx.ty)]
+ vec![DeconstructedPat::wildcard(pcx.ty, pcx.span)]
} else {
let mut split_wildcard = SplitWildcard::new(pcx);
split_wildcard.split(pcx, matrix.heads().map(DeconstructedPat::ctor));
@@ -631,7 +631,7 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
.collect();
if hide_variant_show_wild {
- new.push(DeconstructedPat::wildcard(pcx.ty));
+ new.push(DeconstructedPat::wildcard(pcx.ty, pcx.span));
}
new
@@ -734,7 +734,7 @@ impl<'p, 'tcx> Witness<'p, 'tcx> {
let arity = ctor.arity(pcx);
let pats = self.0.drain((len - arity)..).rev();
let fields = Fields::from_iter(pcx.cx, pats);
- DeconstructedPat::new(ctor.clone(), fields, pcx.ty, DUMMY_SP)
+ DeconstructedPat::new(ctor.clone(), fields, pcx.ty, pcx.span)
};
self.0.push(pat);
@@ -977,7 +977,7 @@ pub(crate) fn compute_match_usefulness<'p, 'tcx>(
})
.collect();
- let wild_pattern = cx.pattern_arena.alloc(DeconstructedPat::wildcard(scrut_ty));
+ let wild_pattern = cx.pattern_arena.alloc(DeconstructedPat::wildcard(scrut_ty, DUMMY_SP));
let v = PatStack::from_pattern(wild_pattern);
let usefulness = is_useful(cx, &matrix, &v, FakeExtraWildcard, scrut_hir_id, false, true);
let non_exhaustiveness_witnesses = match usefulness {
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index d7696a5700061..176027b3b93e4 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -284,7 +284,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return None;
}
- self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&c.literal, Some(c.span), None))
+ // Normalization needed b/c const prop lint runs in
+ // `mir_drops_elaborated_and_const_checked`, which happens before
+ // optimized MIR. Only after optimizing the MIR can we guarantee
+ // that the `RevealAll` pass has happened and that the body's consts
+ // are normalized, so any call to resolve before that needs to be
+ // manually normalized.
+ let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.literal).ok()?;
+
+ self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&val, Some(c.span), None))
}
/// Returns the value, if any, of evaluating `place`.
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index 689d6c71361dd..6a73f2a657813 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -37,8 +37,7 @@ impl CoverageGraph {
// `SwitchInt` to have multiple targets to the same destination `BasicBlock`, so
// de-duplication is required. This is done without reordering the successors.
- let bcbs_len = bcbs.len();
- let mut seen = IndexVec::from_elem_n(false, bcbs_len);
+ let mut seen = IndexVec::from_elem(false, &bcbs);
let successors = IndexVec::from_fn_n(
|bcb| {
for b in seen.iter_mut() {
@@ -60,7 +59,7 @@ impl CoverageGraph {
bcbs.len(),
);
- let mut predecessors = IndexVec::from_elem_n(Vec::new(), bcbs.len());
+ let mut predecessors = IndexVec::from_elem(Vec::new(), &bcbs);
for (bcb, bcb_successors) in successors.iter_enumerated() {
for &successor in bcb_successors {
predecessors[successor].push(bcb);
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index ae8fe90e9d611..6422b8ac1ba45 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -3,6 +3,7 @@ use crate::errors;
use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
+use ast::StaticItem;
use rustc_ast::ast::*;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, TokenKind};
@@ -227,7 +228,7 @@ impl<'a> Parser<'a> {
self.bump(); // `static`
let m = self.parse_mutability();
let (ident, ty, expr) = self.parse_item_global(Some(m))?;
- (ident, ItemKind::Static(ty, m, expr))
+ (ident, ItemKind::Static(Box::new(StaticItem { ty, mutability: m, expr })))
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
// CONST ITEM
if self.token.is_keyword(kw::Impl) {
@@ -236,7 +237,7 @@ impl<'a> Parser<'a> {
} else {
self.recover_const_mut(const_span);
let (ident, ty, expr) = self.parse_item_global(None)?;
- (ident, ItemKind::Const(def_(), ty, expr))
+ (ident, ItemKind::Const(Box::new(ConstItem { defaultness: def_(), ty, expr })))
}
} else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() {
// TRAIT ITEM
@@ -862,9 +863,13 @@ impl<'a> Parser<'a> {
let kind = match AssocItemKind::try_from(kind) {
Ok(kind) => kind,
Err(kind) => match kind {
- ItemKind::Static(a, _, b) => {
+ ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
self.sess.emit_err(errors::AssociatedStaticItemNotAllowed { span });
- AssocItemKind::Const(Defaultness::Final, a, b)
+ AssocItemKind::Const(Box::new(ConstItem {
+ defaultness: Defaultness::Final,
+ ty,
+ expr,
+ }))
}
_ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
},
@@ -1114,12 +1119,12 @@ impl<'a> Parser<'a> {
let kind = match ForeignItemKind::try_from(kind) {
Ok(kind) => kind,
Err(kind) => match kind {
- ItemKind::Const(_, a, b) => {
+ ItemKind::Const(box ConstItem { ty, expr, .. }) => {
self.sess.emit_err(errors::ExternItemCannotBeConst {
ident_span: ident.span,
const_span: span.with_hi(ident.span.lo()),
});
- ForeignItemKind::Static(a, Mutability::Not, b)
+ ForeignItemKind::Static(ty, Mutability::Not, expr)
}
_ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
},
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 19ccb3a6484af..49c41470a1514 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -688,8 +688,8 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
}
// These items live in the value namespace.
- ItemKind::Static(_, mt, _) => {
- let res = Res::Def(DefKind::Static(mt), def_id);
+ ItemKind::Static(box ast::StaticItem { mutability, .. }) => {
+ let res = Res::Def(DefKind::Static(mutability), def_id);
self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
}
ItemKind::Const(..) => {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index b82b07bcf0cc8..19f46d45af678 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -2346,7 +2346,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
});
}
- ItemKind::Static(ref ty, _, ref expr) | ItemKind::Const(_, ref ty, ref expr) => {
+ ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. })
+ | ItemKind::Const(box ast::ConstItem { ref ty, ref expr, .. }) => {
self.with_static_rib(|this| {
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
this.visit_ty(ty);
@@ -2624,11 +2625,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
for item in trait_items {
self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
match &item.kind {
- AssocItemKind::Const(_, ty, default) => {
+ AssocItemKind::Const(box ast::ConstItem { ty, expr, .. }) => {
self.visit_ty(ty);
// Only impose the restrictions of `ConstRibKind` for an
// actual constant expression in a provided default.
- if let Some(expr) = default {
+ if let Some(expr) = expr {
// We allow arbitrary const expressions inside of associated consts,
// even if they are potentially not const evaluatable.
//
@@ -2799,7 +2800,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
use crate::ResolutionError::*;
self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
match &item.kind {
- AssocItemKind::Const(_, ty, default) => {
+ AssocItemKind::Const(box ast::ConstItem { ty, expr, .. }) => {
debug!("resolve_implementation AssocItemKind::Const");
// If this is a trait impl, ensure the const
// exists in trait
@@ -2814,7 +2815,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
);
self.visit_ty(ty);
- if let Some(expr) = default {
+ if let Some(expr) = expr {
// We allow arbitrary const expressions inside of associated consts,
// even if they are potentially not const evaluatable.
//
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 73f86f74d14f1..e8155520c9b78 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -522,7 +522,7 @@ fn generator_saved_local_eligibility(
use SavedLocalEligibility::*;
let mut assignments: IndexVec =
- IndexVec::from_elem_n(Unassigned, info.field_tys.len());
+ IndexVec::from_elem(Unassigned, &info.field_tys);
// The saved locals not eligible for overlap. These will get
// "promoted" to the prefix of our generator.
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 0895bb510d481..02b358e863b66 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1142,22 +1142,21 @@ fn fmt_type<'cx>(
// the ugliness comes from inlining across crates where
// everything comes in as a fully resolved QPath (hard to
// look at).
- match href(trait_.def_id(), cx) {
- Ok((ref url, _, ref path)) if !f.alternate() => {
- write!(
- f,
- "{name}{args}",
- url = url,
- shortty = ItemType::AssocType,
- name = assoc.name,
- path = join_with_double_colon(path),
- args = assoc.args.print(cx),
- )?;
- }
- _ => write!(f, "{}{:#}", assoc.name, assoc.args.print(cx))?,
- }
- Ok(())
+ if !f.alternate() && let Ok((url, _, path)) = href(trait_.def_id(), cx) {
+ write!(
+ f,
+ "{name}",
+ shortty = ItemType::AssocType,
+ name = assoc.name,
+ path = join_with_double_colon(&path),
+ )
+ } else {
+ write!(f, "{}", assoc.name)
+ }?;
+
+ // Carry `f.alternate()` into this display w/o branching manually.
+ fmt::Display::fmt(&assoc.args.print(cx), f)
}
}
}
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 060062db0027a..c959bb3701ab5 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -421,12 +421,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
| hir::ItemKind::Struct(..)
| hir::ItemKind::Union(..)
| hir::ItemKind::TyAlias(..)
- | hir::ItemKind::OpaqueTy(..)
+ | hir::ItemKind::OpaqueTy(hir::OpaqueTy {
+ origin: hir::OpaqueTyOrigin::TyAlias, ..
+ })
| hir::ItemKind::Static(..)
| hir::ItemKind::Trait(..)
| hir::ItemKind::TraitAlias(..) => {
self.add_to_current_mod(item, renamed, import_id);
}
+ hir::ItemKind::OpaqueTy(hir::OpaqueTy {
+ origin: hir::OpaqueTyOrigin::AsyncFn(_) | hir::OpaqueTyOrigin::FnReturn(_),
+ ..
+ }) => {
+ // return-position impl traits are never nameable, and should never be documented.
+ }
hir::ItemKind::Const(..) => {
// Underscore constants do not correspond to a nameable item and
// so are never useful in documentation.
diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
index 44bf824aa0e2d..11b908e7e53d1 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::snippet;
-use rustc_ast::ast::{Item, ItemKind, Ty, TyKind};
+use rustc_ast::ast::{Item, ItemKind, Ty, TyKind, StaticItem, ConstItem};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -100,13 +100,13 @@ impl EarlyLintPass for RedundantStaticLifetimes {
}
if !item.span.from_expansion() {
- if let ItemKind::Const(_, ref var_type, _) = item.kind {
+ if let ItemKind::Const(box ConstItem { ty: ref var_type, .. }) = item.kind {
Self::visit_type(var_type, cx, "constants have by default a `'static` lifetime");
// Don't check associated consts because `'static` cannot be elided on those (issue
// #2438)
}
- if let ItemKind::Static(ref var_type, _, _) = item.kind {
+ if let ItemKind::Static(box StaticItem { ty: ref var_type,.. }) = item.kind {
Self::visit_type(var_type, cx, "statics have by default a `'static` lifetime");
}
}
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index d2dedc2043957..c5b58b0c060c0 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -286,8 +286,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
match (l, r) {
(ExternCrate(l), ExternCrate(r)) => l == r,
(Use(l), Use(r)) => eq_use_tree(l, r),
- (Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
- (Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
+ (Static(box ast::StaticItem { ty: lt, mutability: lm, expr: le}), Static(box ast::StaticItem { ty: rt, mutability: rm, expr: re})) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
+ (Const(box ast::ConstItem { defaultness: ld, ty: lt, expr: le}), Const(box ast::ConstItem { defaultness: rd, ty: rt, expr: re} )) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
(
Fn(box ast::Fn {
defaultness: ld,
@@ -451,7 +451,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
use AssocItemKind::*;
match (l, r) {
- (Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
+ (Const(box ast::ConstItem { defaultness: ld, ty: lt, expr: le}), Const(box ast::ConstItem { defaultness: rd, ty: rt, expr: re})) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
(
Fn(box ast::Fn {
defaultness: ld,
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 25e8a024857ce..43779cfaecd3a 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -1804,13 +1804,15 @@ pub(crate) struct StaticParts<'a> {
impl<'a> StaticParts<'a> {
pub(crate) fn from_item(item: &'a ast::Item) -> Self {
- let (defaultness, prefix, ty, mutability, expr) = match item.kind {
- ast::ItemKind::Static(ref ty, mutability, ref expr) => {
- (None, "static", ty, mutability, expr)
- }
- ast::ItemKind::Const(defaultness, ref ty, ref expr) => {
- (Some(defaultness), "const", ty, ast::Mutability::Not, expr)
- }
+ let (defaultness, prefix, ty, mutability, expr) = match &item.kind {
+ ast::ItemKind::Static(s) => (None, "static", &s.ty, s.mutability, &s.expr),
+ ast::ItemKind::Const(c) => (
+ Some(c.defaultness),
+ "const",
+ &c.ty,
+ ast::Mutability::Not,
+ &c.expr,
+ ),
_ => unreachable!(),
};
StaticParts {
@@ -1826,10 +1828,8 @@ impl<'a> StaticParts<'a> {
}
pub(crate) fn from_trait_item(ti: &'a ast::AssocItem) -> Self {
- let (defaultness, ty, expr_opt) = match ti.kind {
- ast::AssocItemKind::Const(defaultness, ref ty, ref expr_opt) => {
- (defaultness, ty, expr_opt)
- }
+ let (defaultness, ty, expr_opt) = match &ti.kind {
+ ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr),
_ => unreachable!(),
};
StaticParts {
@@ -1845,8 +1845,8 @@ impl<'a> StaticParts<'a> {
}
pub(crate) fn from_impl_item(ii: &'a ast::AssocItem) -> Self {
- let (defaultness, ty, expr) = match ii.kind {
- ast::AssocItemKind::Const(defaultness, ref ty, ref expr) => (defaultness, ty, expr),
+ let (defaultness, ty, expr) = match &ii.kind {
+ ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr),
_ => unreachable!(),
};
StaticParts {
diff --git a/tests/rustdoc/async-fn-opaque-item.rs b/tests/rustdoc/async-fn-opaque-item.rs
new file mode 100644
index 0000000000000..a73e84f3fdc4e
--- /dev/null
+++ b/tests/rustdoc/async-fn-opaque-item.rs
@@ -0,0 +1,15 @@
+// compile-flags: --document-private-items --crate-type=lib
+// edition: 2021
+
+// Issue 109931 -- test against accidentally documenting the `impl Future`
+// that comes from an async fn desugaring.
+
+// Check that we don't document an unnamed opaque type
+// @!has async_fn_opaque_item/opaque..html
+
+// Checking there is only a "Functions" header and no "Opaque types".
+// @has async_fn_opaque_item/index.html
+// @count - '//*[@class="small-section-header"]' 1
+// @has - '//*[@class="small-section-header"]' 'Functions'
+
+pub async fn test() {}
diff --git a/tests/rustdoc/generic-associated-types/issue-109488.rs b/tests/rustdoc/generic-associated-types/issue-109488.rs
new file mode 100644
index 0000000000000..99ae8a6c36c52
--- /dev/null
+++ b/tests/rustdoc/generic-associated-types/issue-109488.rs
@@ -0,0 +1,18 @@
+// Make sure that we escape the arguments of the GAT projection even if we fail to compute
+// the href of the corresponding trait (in this case it is private).
+// Further, test that we also linkify the GAT arguments.
+
+// @has 'issue_109488/type.A.html'
+// @has - '//pre[@class="rust item-decl"]' '
::P