,
+ items: Vec>,
+ },
/// A macro invocation.
///
/// E.g., `foo!(..)`.
@@ -2754,9 +2736,6 @@ pub enum ItemKind {
MacroDef(MacroDef),
}
-#[cfg(target_arch = "x86_64")]
-rustc_data_structures::static_assert_size!(ItemKind, 112);
-
impl ItemKind {
pub fn article(&self) -> &str {
use ItemKind::*;
@@ -2791,14 +2770,14 @@ impl ItemKind {
pub fn generics(&self) -> Option<&Generics> {
match self {
- Self::Fn(box FnKind(_, _, generics, _))
- | Self::TyAlias(box TyAliasKind(_, generics, ..))
+ Self::Fn(_, _, generics, _)
+ | Self::TyAlias(_, generics, ..)
| Self::Enum(_, generics)
| Self::Struct(_, generics)
| Self::Union(_, generics)
- | Self::Trait(box TraitKind(_, _, generics, ..))
+ | Self::Trait(_, _, generics, ..)
| Self::TraitAlias(generics, _)
- | Self::Impl(box ImplKind { generics, .. }) => Some(generics),
+ | Self::Impl { generics, .. } => Some(generics),
_ => None,
}
}
@@ -2821,22 +2800,17 @@ pub enum AssocItemKind {
/// If `def` is parsed, then the constant is provided, and otherwise required.
Const(Defaultness, P, Option>),
/// An associated function.
- Fn(Box),
+ Fn(Defaultness, FnSig, Generics, Option>),
/// An associated type.
- TyAlias(Box),
+ TyAlias(Defaultness, Generics, GenericBounds, Option>),
/// A macro expanding to associated items.
MacCall(MacCall),
}
-#[cfg(target_arch = "x86_64")]
-rustc_data_structures::static_assert_size!(AssocItemKind, 72);
-
impl AssocItemKind {
pub fn defaultness(&self) -> Defaultness {
match *self {
- Self::Const(def, ..)
- | Self::Fn(box FnKind(def, ..))
- | Self::TyAlias(box TyAliasKind(def, ..)) => def,
+ Self::Const(def, ..) | Self::Fn(def, ..) | Self::TyAlias(def, ..) => def,
Self::MacCall(..) => Defaultness::Final,
}
}
@@ -2846,8 +2820,8 @@ 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::Fn(fn_kind) => ItemKind::Fn(fn_kind),
- AssocItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
+ AssocItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d),
+ AssocItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d),
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
}
}
@@ -2859,8 +2833,8 @@ 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::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
- ItemKind::TyAlias(ty_alias_kind) => AssocItemKind::TyAlias(ty_alias_kind),
+ ItemKind::Fn(a, b, c, d) => AssocItemKind::Fn(a, b, c, d),
+ ItemKind::TyAlias(a, b, c, d) => AssocItemKind::TyAlias(a, b, c, d),
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
_ => return Err(item_kind),
})
@@ -2872,23 +2846,20 @@ impl TryFrom for AssocItemKind {
pub enum ForeignItemKind {
/// A foreign static item (`static FOO: u8`).
Static(P, Mutability, Option>),
- /// An foreign function.
- Fn(Box),
- /// An foreign type.
- TyAlias(Box),
+ /// A foreign function.
+ Fn(Defaultness, FnSig, Generics, Option>),
+ /// A foreign type.
+ TyAlias(Defaultness, Generics, GenericBounds, Option
>),
/// A macro expanding to foreign items.
MacCall(MacCall),
}
-#[cfg(target_arch = "x86_64")]
-rustc_data_structures::static_assert_size!(ForeignItemKind, 72);
-
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::Fn(fn_kind) => ItemKind::Fn(fn_kind),
- ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
+ ForeignItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d),
+ ForeignItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d),
ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
}
}
@@ -2900,8 +2871,8 @@ 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::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
- ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
+ ItemKind::Fn(a, b, c, d) => ForeignItemKind::Fn(a, b, c, d),
+ ItemKind::TyAlias(a, b, c, d) => ForeignItemKind::TyAlias(a, b, c, d),
ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
_ => return Err(item_kind),
})
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index ddf52caed088a..08695491de756 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -9,11 +9,11 @@
test(attr(deny(warnings)))
)]
#![feature(box_syntax)]
-#![feature(box_patterns)]
#![feature(const_fn)] // For the `transmute` in `P::new`
#![feature(const_fn_transmute)]
#![feature(const_panic)]
#![feature(crate_visibility_modifier)]
+#![feature(iterator_fold_self)]
#![feature(label_break_value)]
#![feature(nll)]
#![feature(or_patterns)]
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 024d9687f3119..35de744d274c9 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -28,7 +28,7 @@ pub trait ExpectOne {
impl ExpectOne for SmallVec {
fn expect_one(self, err: &'static str) -> A::Item {
- assert!(self.len() == 1, "{}", err);
+ assert!(self.len() == 1, err);
self.into_iter().next().unwrap()
}
}
@@ -912,7 +912,7 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) {
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
}
- ItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+ ItemKind::Fn(_, sig, generics, body) => {
visit_fn_sig(sig, vis);
vis.visit_generics(generics);
visit_opt(body, |body| vis.visit_block(body));
@@ -920,7 +920,7 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) {
ItemKind::Mod(m) => vis.visit_mod(m),
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(_ga) => {}
- ItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+ ItemKind::TyAlias(_, generics, bounds, ty) => {
vis.visit_generics(generics);
visit_bounds(bounds, vis);
visit_opt(ty, |ty| vis.visit_ty(ty));
@@ -933,7 +933,7 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) {
vis.visit_variant_data(variant_data);
vis.visit_generics(generics);
}
- ItemKind::Impl(box ImplKind {
+ ItemKind::Impl {
unsafety: _,
polarity: _,
defaultness: _,
@@ -942,13 +942,13 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) {
of_trait,
self_ty,
items,
- }) => {
+ } => {
vis.visit_generics(generics);
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
vis.visit_ty(self_ty);
items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
}
- ItemKind::Trait(box TraitKind(.., generics, bounds, items)) => {
+ ItemKind::Trait(_is_auto, _unsafety, generics, bounds, items) => {
vis.visit_generics(generics);
visit_bounds(bounds, vis);
items.flat_map_in_place(|item| vis.flat_map_trait_item(item));
@@ -976,12 +976,12 @@ pub fn noop_flat_map_assoc_item(
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
}
- AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+ AssocItemKind::Fn(_, sig, generics, body) => {
visitor.visit_generics(generics);
visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body));
}
- AssocItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+ AssocItemKind::TyAlias(_, generics, bounds, ty) => {
visitor.visit_generics(generics);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
@@ -1066,12 +1066,12 @@ pub fn noop_flat_map_foreign_item(
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
}
- ForeignItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+ ForeignItemKind::Fn(_, sig, generics, body) => {
visitor.visit_generics(generics);
visit_fn_sig(sig, visitor);
visit_opt(body, |body| visitor.visit_block(body));
}
- ForeignItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+ ForeignItemKind::TyAlias(_, generics, bounds, ty) => {
visitor.visit_generics(generics);
visit_bounds(bounds, visitor);
visit_opt(ty, |ty| visitor.visit_ty(ty));
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index c37d4cd9f7936..2ba1c49edfa44 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -292,7 +292,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_ty(typ);
walk_list!(visitor, visit_expr, expr);
}
- ItemKind::Fn(box FnKind(_, ref sig, ref generics, ref body)) => {
+ ItemKind::Fn(_, ref sig, ref generics, ref body) => {
visitor.visit_generics(generics);
let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref());
visitor.visit_fn(kind, item.span, item.id)
@@ -302,7 +302,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
}
ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga),
- ItemKind::TyAlias(box TyAliasKind(_, ref generics, ref bounds, ref ty)) => {
+ ItemKind::TyAlias(_, ref generics, ref bounds, ref ty) => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty);
@@ -311,7 +311,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_generics(generics);
visitor.visit_enum_def(enum_definition, generics, item.id, item.span)
}
- ItemKind::Impl(box ImplKind {
+ ItemKind::Impl {
unsafety: _,
polarity: _,
defaultness: _,
@@ -320,7 +320,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
ref of_trait,
ref self_ty,
ref items,
- }) => {
+ } => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_trait_ref, of_trait);
visitor.visit_ty(self_ty);
@@ -331,7 +331,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_generics(generics);
visitor.visit_variant_data(struct_definition);
}
- ItemKind::Trait(box TraitKind(.., ref generics, ref bounds, ref items)) => {
+ ItemKind::Trait(.., ref generics, ref bounds, ref items) => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
@@ -543,12 +543,12 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI
visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr);
}
- ForeignItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+ ForeignItemKind::Fn(_, sig, generics, body) => {
visitor.visit_generics(generics);
let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, body.as_deref());
visitor.visit_fn(kind, span, id);
}
- ForeignItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+ ForeignItemKind::TyAlias(_, generics, bounds, ty) => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty);
@@ -653,12 +653,12 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
visitor.visit_ty(ty);
walk_list!(visitor, visit_expr, expr);
}
- AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+ AssocItemKind::Fn(_, sig, generics, body) => {
visitor.visit_generics(generics);
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, body.as_deref());
visitor.visit_fn(kind, span, id);
}
- AssocItemKind::TyAlias(box TyAliasKind(_, generics, bounds, ty)) => {
+ AssocItemKind::TyAlias(_, generics, bounds, ty) => {
visitor.visit_generics(generics);
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, ty);
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 1efe83cacea4a..69257ce1c19e9 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -67,7 +67,7 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
if let Some(hir_id) = item_hir_id {
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
let this = &mut ItemLowerer { lctx: this };
- if let ItemKind::Impl(box ImplKind { ref of_trait, .. }) = item.kind {
+ if let ItemKind::Impl { ref of_trait, .. } = item.kind {
this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
} else {
visit::walk_item(this, item);
@@ -189,9 +189,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
vec
}
ItemKind::MacroDef(..) => SmallVec::new(),
- ItemKind::Fn(..) | ItemKind::Impl(box ImplKind { of_trait: None, .. }) => {
- smallvec![i.id]
- }
+ ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id],
_ => smallvec![i.id],
};
@@ -278,12 +276,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
hir::ItemKind::Const(ty, body_id)
}
- ItemKind::Fn(box FnKind(
+ ItemKind::Fn(
_,
FnSig { ref decl, header, span: fn_sig_span },
ref generics,
ref body,
- )) => {
+ ) => {
let fn_def_id = self.resolver.local_def_id(id);
self.with_new_scopes(|this| {
this.current_item = Some(ident.span);
@@ -331,7 +329,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
- ItemKind::TyAlias(box TyAliasKind(_, ref gen, _, Some(ref ty))) => {
+ ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => {
// We lower
//
// type Foo = impl Trait
@@ -350,7 +348,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let generics = self.lower_generics(gen, ImplTraitContext::disallowed());
hir::ItemKind::TyAlias(ty, generics)
}
- ItemKind::TyAlias(box TyAliasKind(_, ref generics, _, None)) => {
+ ItemKind::TyAlias(_, ref generics, _, None) => {
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
hir::ItemKind::TyAlias(ty, generics)
@@ -377,7 +375,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_generics(generics, ImplTraitContext::disallowed()),
)
}
- ItemKind::Impl(box ImplKind {
+ ItemKind::Impl {
unsafety,
polarity,
defaultness,
@@ -386,7 +384,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
of_trait: ref trait_ref,
self_ty: ref ty,
items: ref impl_items,
- }) => {
+ } => {
let def_id = self.resolver.local_def_id(id);
// Lower the "impl header" first. This ordering is important
@@ -450,13 +448,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
items: new_impl_items,
})
}
- ItemKind::Trait(box TraitKind(
- is_auto,
- unsafety,
- ref generics,
- ref bounds,
- ref items,
- )) => {
+ ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
let items = self
.arena
@@ -706,7 +698,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ident: i.ident,
attrs: self.lower_attrs(&i.attrs),
kind: match i.kind {
- ForeignItemKind::Fn(box FnKind(_, ref sig, ref generics, _)) => {
+ ForeignItemKind::Fn(_, ref sig, ref generics, _) => {
let fdec = &sig.decl;
let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
generics,
@@ -811,19 +803,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body))
}
- AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, None)) => {
+ AssocItemKind::Fn(_, ref sig, ref generics, None) => {
let names = self.lower_fn_params_to_names(&sig.decl);
let (generics, sig) =
self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
}
- AssocItemKind::Fn(box FnKind(_, ref sig, ref generics, Some(ref body))) => {
+ AssocItemKind::Fn(_, ref sig, ref generics, Some(ref body)) => {
let body_id = self.lower_fn_body_block(i.span, &sig.decl, Some(body));
let (generics, sig) =
self.lower_method_sig(generics, sig, trait_item_def_id, false, None, i.id);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
}
- AssocItemKind::TyAlias(box TyAliasKind(_, ref generics, ref bounds, ref default)) => {
+ AssocItemKind::TyAlias(_, ref generics, ref bounds, ref default) => {
let ty = default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed()));
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let kind = hir::TraitItemKind::Type(
@@ -849,10 +841,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
let (kind, has_default) = match &i.kind {
AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()),
- AssocItemKind::TyAlias(box TyAliasKind(_, _, _, default)) => {
+ AssocItemKind::TyAlias(_, _, _, default) => {
(hir::AssocItemKind::Type, default.is_some())
}
- AssocItemKind::Fn(box FnKind(_, sig, _, default)) => {
+ AssocItemKind::Fn(_, sig, _, default) => {
(hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, default.is_some())
}
AssocItemKind::MacCall(..) => unimplemented!(),
@@ -878,7 +870,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
)
}
- AssocItemKind::Fn(box FnKind(_, sig, generics, body)) => {
+ AssocItemKind::Fn(_, sig, generics, body) => {
self.current_item = Some(i.span);
let asyncness = sig.header.asyncness;
let body_id =
@@ -895,7 +887,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
(generics, hir::ImplItemKind::Fn(sig, body_id))
}
- AssocItemKind::TyAlias(box TyAliasKind(_, generics, _, ty)) => {
+ AssocItemKind::TyAlias(_, generics, _, ty) => {
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let kind = match ty {
None => {
@@ -946,7 +938,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
kind: match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const,
AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type,
- AssocItemKind::Fn(box FnKind(_, sig, ..)) => {
+ AssocItemKind::Fn(_, sig, ..) => {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
}
AssocItemKind::MacCall(..) => unimplemented!(),
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index f076dca5cf5f1..8f2e49e299c8b 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -32,7 +32,6 @@
#![feature(crate_visibility_modifier)]
#![feature(or_patterns)]
-#![feature(box_patterns)]
#![recursion_limit = "256"]
use rustc_ast::node_id::NodeMap;
@@ -501,15 +500,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ItemKind::Struct(_, ref generics)
| ItemKind::Union(_, ref generics)
| ItemKind::Enum(_, ref generics)
- | ItemKind::TyAlias(box TyAliasKind(_, ref generics, ..))
- | ItemKind::Trait(box TraitKind(_, _, ref generics, ..)) => {
+ | ItemKind::TyAlias(_, ref generics, ..)
+ | ItemKind::Trait(_, _, ref generics, ..) => {
let def_id = self.lctx.resolver.local_def_id(item.id);
let count = generics
.params
.iter()
- .filter(|param| {
- matches!(param.kind, ast::GenericParamKind::Lifetime { .. })
- })
+ .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime { .. }))
.count();
self.lctx.type_def_lifetime_params.insert(def_id.to_def_id(), count);
}
@@ -1076,40 +1073,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_assoc_ty_constraint(
&mut self,
constraint: &AssocTyConstraint,
- mut itctx: ImplTraitContext<'_, 'hir>,
+ itctx: ImplTraitContext<'_, 'hir>,
) -> hir::TypeBinding<'hir> {
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
- // lower generic arguments of identifier in constraint
- let gen_args = if let Some(ref gen_args) = constraint.gen_args {
- let gen_args_ctor = match gen_args {
- GenericArgs::AngleBracketed(ref data) => {
- self.lower_angle_bracketed_parameter_data(
- data,
- ParamMode::Explicit,
- itctx.reborrow(),
- )
- .0
- }
- GenericArgs::Parenthesized(ref data) => {
- let mut err = self.sess.struct_span_err(
- gen_args.span(),
- "parenthesized generic arguments cannot be used in associated type constraints"
- );
- // FIXME: try to write a suggestion here
- err.emit();
- self.lower_angle_bracketed_parameter_data(
- &data.as_angle_bracketed_args(),
- ParamMode::Explicit,
- itctx.reborrow(),
- )
- .0
- }
- };
- self.arena.alloc(gen_args_ctor.into_generic_args(&self.arena))
- } else {
- self.arena.alloc(hir::GenericArgs::none())
- };
+ if let Some(ref gen_args) = constraint.gen_args {
+ self.sess.span_fatal(
+ gen_args.span(),
+ "generic associated types in trait paths are currently not implemented",
+ );
+ }
let kind = match constraint.kind {
AssocTyConstraintKind::Equality { ref ty } => {
@@ -1206,7 +1179,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::TypeBinding {
hir_id: self.lower_node_id(constraint.id),
ident: constraint.ident,
- gen_args,
kind,
span: constraint.span,
}
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index cb4d5ea6ee650..9079e26eb509e 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -362,7 +362,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
- pub(crate) fn lower_angle_bracketed_parameter_data(
+ fn lower_angle_bracketed_parameter_data(
&mut self,
data: &AngleBracketedArgs,
param_mode: ParamMode,
@@ -426,9 +426,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) -> hir::TypeBinding<'hir> {
let ident = Ident::with_dummy_span(hir::FN_OUTPUT_NAME);
let kind = hir::TypeBindingKind::Equality { ty };
- let args = arena_vec![self;];
- let bindings = arena_vec![self;];
- let gen_args = self.arena.alloc(hir::GenericArgs { args, bindings, parenthesized: false });
- hir::TypeBinding { hir_id: self.next_id(), gen_args, span, ident, kind }
+ hir::TypeBinding { hir_id: self.next_id(), span, ident, kind }
}
}
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 8defd91c688d7..baeadb216dc3a 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -920,7 +920,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
match item.kind {
- ItemKind::Impl(box ImplKind {
+ ItemKind::Impl {
unsafety,
polarity,
defaultness: _,
@@ -929,7 +929,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
of_trait: Some(ref t),
ref self_ty,
items: _,
- }) => {
+ } => {
self.with_in_trait_impl(true, |this| {
this.invalid_visibility(&item.vis, None);
if let TyKind::Err = self_ty.kind {
@@ -957,7 +957,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
});
return; // Avoid visiting again.
}
- ItemKind::Impl(box ImplKind {
+ ItemKind::Impl {
unsafety,
polarity,
defaultness,
@@ -966,7 +966,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
of_trait: None,
ref self_ty,
items: _,
- }) => {
+ } => {
let error = |annotation_span, annotation| {
let mut err = self.err_handler().struct_span_err(
self_ty.span,
@@ -998,7 +998,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.emit();
}
}
- ItemKind::Fn(box FnKind(def, _, _, ref body)) => {
+ ItemKind::Fn(def, _, _, ref body) => {
self.check_defaultness(item.span, def);
if body.is_none() {
@@ -1027,13 +1027,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
}
- ItemKind::Trait(box TraitKind(
- is_auto,
- _,
- ref generics,
- ref bounds,
- ref trait_items,
- )) => {
+ ItemKind::Trait(is_auto, _, ref generics, ref bounds, ref trait_items) => {
if is_auto == IsAuto::Yes {
// Auto traits cannot have generics, super traits nor contain items.
self.deny_generic_params(generics, item.ident.span);
@@ -1081,7 +1075,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
let msg = "free static item without body";
self.error_item_without_body(item.span, "static", msg, " = ;");
}
- ItemKind::TyAlias(box TyAliasKind(def, _, ref bounds, ref body)) => {
+ ItemKind::TyAlias(def, _, ref bounds, ref body) => {
self.check_defaultness(item.span, def);
if body.is_none() {
let msg = "free type alias without body";
@@ -1097,12 +1091,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
match &fi.kind {
- ForeignItemKind::Fn(box FnKind(def, sig, _, body)) => {
+ ForeignItemKind::Fn(def, sig, _, body) => {
self.check_defaultness(fi.span, *def);
self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
}
- ForeignItemKind::TyAlias(box TyAliasKind(def, generics, bounds, body)) => {
+ ForeignItemKind::TyAlias(def, generics, bounds, body) => {
self.check_defaultness(fi.span, *def);
self.check_foreign_kind_bodyless(fi.ident, "type", body.as_ref().map(|b| b.span));
self.check_type_no_bounds(bounds, "`extern` blocks");
@@ -1342,10 +1336,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
AssocItemKind::Const(_, _, body) => {
self.check_impl_item_provided(item.span, body, "constant", " = ;");
}
- AssocItemKind::Fn(box FnKind(_, _, _, body)) => {
+ AssocItemKind::Fn(_, _, _, body) => {
self.check_impl_item_provided(item.span, body, "function", " { }");
}
- AssocItemKind::TyAlias(box TyAliasKind(_, _, bounds, body)) => {
+ AssocItemKind::TyAlias(_, _, bounds, body) => {
self.check_impl_item_provided(item.span, body, "type", " = ;");
self.check_type_no_bounds(bounds, "`impl`s");
}
@@ -1355,7 +1349,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
self.invalid_visibility(&item.vis, None);
- if let AssocItemKind::Fn(box FnKind(_, sig, _, _)) = &item.kind {
+ if let AssocItemKind::Fn(_, sig, _, _) = &item.kind {
self.check_trait_fn_not_const(sig.header.constness);
self.check_trait_fn_not_async(item.span, sig.header.asyncness);
}
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 6514de2b81315..7bd805f91c857 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -156,14 +156,6 @@ impl<'a> PostExpansionVisitor<'a> {
"efiapi ABI is experimental and subject to change"
);
}
- "C-cmse-nonsecure-call" => {
- gate_feature_post!(
- &self,
- abi_c_cmse_nonsecure_call,
- span,
- "C-cmse-nonsecure-call ABI is experimental and subject to change"
- );
- }
abi => self
.sess
.parse_sess
@@ -373,9 +365,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
- ast::ItemKind::Impl(box ast::ImplKind {
- polarity, defaultness, ref of_trait, ..
- }) => {
+ ast::ItemKind::Impl { polarity, defaultness, ref of_trait, .. } => {
if let ast::ImplPolarity::Negative(span) = polarity {
gate_feature_post!(
&self,
@@ -391,7 +381,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
}
- ast::ItemKind::Trait(box ast::TraitKind(ast::IsAuto::Yes, ..)) => {
+ ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => {
gate_feature_post!(
&self,
auto_traits,
@@ -409,9 +399,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
gate_feature_post!(&self, decl_macro, i.span, msg);
}
- ast::ItemKind::TyAlias(box ast::TyAliasKind(_, _, _, Some(ref ty))) => {
- self.check_impl_trait(&ty)
- }
+ ast::ItemKind::TyAlias(_, _, _, Some(ref ty)) => self.check_impl_trait(&ty),
_ => {}
}
@@ -567,13 +555,13 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
let is_fn = match i.kind {
- ast::AssocItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) => {
+ ast::AssocItemKind::Fn(_, ref sig, _, _) => {
if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) {
gate_feature_post!(&self, const_fn, i.span, "const fn is unstable");
}
true
}
- ast::AssocItemKind::TyAlias(box ast::TyAliasKind(_, ref generics, _, ref ty)) => {
+ ast::AssocItemKind::TyAlias(_, ref generics, _, ref ty) => {
if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
gate_feature_post!(
&self,
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index c9e2d202da97c..7487421e709a7 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -6,8 +6,6 @@
#![feature(bindings_after_at)]
#![feature(iter_is_partitioned)]
-#![feature(box_syntax)]
-#![feature(box_patterns)]
#![recursion_limit = "256"]
pub mod ast_validation;
diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs
index 2971fa435c8dc..6efc78c88427e 100644
--- a/compiler/rustc_ast_passes/src/node_count.rs
+++ b/compiler/rustc_ast_passes/src/node_count.rs
@@ -68,7 +68,7 @@ impl<'ast> Visitor<'ast> for NodeCounter {
self.count += 1;
walk_generics(self, g)
}
- fn visit_fn(&mut self, fk: visit::FnKind<'_>, s: Span, _: NodeId) {
+ fn visit_fn(&mut self, fk: FnKind<'_>, s: Span, _: NodeId) {
self.count += 1;
walk_fn(self, fk, s)
}
diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index d869baad012ed..9adc6c604e8ab 100644
--- a/compiler/rustc_ast_pretty/src/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
@@ -1,7 +1,6 @@
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(or_patterns)]
-#![feature(box_patterns)]
#![recursion_limit = "256"]
mod helpers;
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 01e234c9be972..2c8caf68f00da 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1022,14 +1022,14 @@ impl<'a> State<'a> {
self.maybe_print_comment(span.lo());
self.print_outer_attributes(attrs);
match kind {
- ast::ForeignItemKind::Fn(box ast::FnKind(def, sig, gen, body)) => {
+ ast::ForeignItemKind::Fn(def, sig, gen, body) => {
self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs);
}
ast::ForeignItemKind::Static(ty, mutbl, body) => {
let def = ast::Defaultness::Final;
self.print_item_const(ident, Some(*mutbl), ty, body.as_deref(), vis, def);
}
- ast::ForeignItemKind::TyAlias(box ast::TyAliasKind(def, generics, bounds, ty)) => {
+ ast::ForeignItemKind::TyAlias(def, generics, bounds, ty) => {
self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def);
}
ast::ForeignItemKind::MacCall(m) => {
@@ -1134,7 +1134,7 @@ impl<'a> State<'a> {
ast::ItemKind::Const(def, ref ty, ref body) => {
self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def);
}
- ast::ItemKind::Fn(box ast::FnKind(def, ref sig, ref gen, ref body)) => {
+ ast::ItemKind::Fn(def, ref sig, ref gen, ref body) => {
let body = body.as_deref();
self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs);
}
@@ -1175,7 +1175,7 @@ impl<'a> State<'a> {
self.s.word(ga.asm.to_string());
self.end();
}
- ast::ItemKind::TyAlias(box ast::TyAliasKind(def, ref generics, ref bounds, ref ty)) => {
+ ast::ItemKind::TyAlias(def, ref generics, ref bounds, ref ty) => {
let ty = ty.as_deref();
self.print_associated_type(item.ident, generics, bounds, ty, &item.vis, def);
}
@@ -1190,7 +1190,7 @@ impl<'a> State<'a> {
self.head(visibility_qualified(&item.vis, "union"));
self.print_struct(struct_def, generics, item.ident, item.span, true);
}
- ast::ItemKind::Impl(box ast::ImplKind {
+ ast::ItemKind::Impl {
unsafety,
polarity,
defaultness,
@@ -1199,7 +1199,7 @@ impl<'a> State<'a> {
ref of_trait,
ref self_ty,
ref items,
- }) => {
+ } => {
self.head("");
self.print_visibility(&item.vis);
self.print_defaultness(defaultness);
@@ -1233,13 +1233,7 @@ impl<'a> State<'a> {
}
self.bclose(item.span);
}
- ast::ItemKind::Trait(box ast::TraitKind(
- is_auto,
- unsafety,
- ref generics,
- ref bounds,
- ref trait_items,
- )) => {
+ ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
self.head("");
self.print_visibility(&item.vis);
self.print_unsafety(unsafety);
@@ -1311,9 +1305,6 @@ impl<'a> State<'a> {
true,
item.span,
);
- if macro_def.body.need_semicolon() {
- self.word(";");
- }
}
}
self.ann.post(self, AnnNode::Item(item))
@@ -1462,13 +1453,13 @@ impl<'a> State<'a> {
self.maybe_print_comment(span.lo());
self.print_outer_attributes(attrs);
match kind {
- ast::AssocItemKind::Fn(box ast::FnKind(def, sig, gen, body)) => {
+ ast::AssocItemKind::Fn(def, sig, gen, body) => {
self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs);
}
ast::AssocItemKind::Const(def, ty, body) => {
self.print_item_const(ident, None, ty, body.as_deref(), vis, *def);
}
- ast::AssocItemKind::TyAlias(box ast::TyAliasKind(def, generics, bounds, ty)) => {
+ ast::AssocItemKind::TyAlias(def, generics, bounds, ty) => {
self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def);
}
ast::AssocItemKind::MacCall(m) => {
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index aca3fbbca1357..696d5fdd6cd45 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -74,7 +74,7 @@ pub enum InlineAttr {
Never,
}
-#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq)]
+#[derive(Clone, Encodable, Decodable, Debug)]
pub enum InstructionSetAttr {
ArmA32,
ArmT32,
diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml
index eb022b5b2b16e..c397a85412627 100644
--- a/compiler/rustc_builtin_macros/Cargo.toml
+++ b/compiler/rustc_builtin_macros/Cargo.toml
@@ -15,7 +15,6 @@ rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
-rustc_lexer = { path = "../rustc_lexer" }
rustc_parse = { path = "../rustc_parse" }
rustc_target = { path = "../rustc_target" }
rustc_session = { path = "../rustc_session" }
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 93ba54da3424e..f82269c4eee4f 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -29,11 +29,11 @@ pub fn expand_assert<'cx>(
let panic_call = if let Some(tokens) = custom_message {
let path = if span.rust_2021() {
- // On edition 2021, we always call `$crate::panic::panic_2021!()`.
+ // On edition 2021, we always call `$crate::panic!()`.
Path {
span: sp,
segments: cx
- .std_path(&[sym::panic, sym::panic_2021])
+ .std_path(&[sym::panic])
.into_iter()
.map(|ident| PathSegment::from_ident(ident))
.collect(),
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
deleted file mode 100644
index fad64858ce3ff..0000000000000
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ /dev/null
@@ -1,132 +0,0 @@
-use rustc_ast::{self as ast, token, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
-use rustc_errors::{struct_span_err, Applicability};
-use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
-use rustc_expand::config::StripUnconfigured;
-use rustc_feature::AttributeTemplate;
-use rustc_parse::validate_attr;
-use rustc_session::Session;
-use rustc_span::symbol::sym;
-use rustc_span::Span;
-
-crate struct Expander;
-
-impl MultiItemModifier for Expander {
- fn expand(
- &self,
- ecx: &mut ExtCtxt<'_>,
- span: Span,
- meta_item: &ast::MetaItem,
- item: Annotatable,
- ) -> ExpandResult, Annotatable> {
- let sess = ecx.sess;
- if report_bad_target(sess, &item, span) {
- // We don't want to pass inappropriate targets to derive macros to avoid
- // follow up errors, all other errors below are recoverable.
- return ExpandResult::Ready(vec![item]);
- }
-
- let template =
- AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
- let attr = ecx.attribute(meta_item.clone());
- validate_attr::check_builtin_attribute(&sess.parse_sess, &attr, sym::derive, template);
-
- let derives: Vec<_> = attr
- .meta_item_list()
- .unwrap_or_default()
- .into_iter()
- .filter_map(|nested_meta| match nested_meta {
- NestedMetaItem::MetaItem(meta) => Some(meta),
- NestedMetaItem::Literal(lit) => {
- // Reject `#[derive("Debug")]`.
- report_unexpected_literal(sess, &lit);
- None
- }
- })
- .map(|meta| {
- // Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the paths.
- report_path_args(sess, &meta);
- meta.path
- })
- .collect();
-
- // FIXME: Try to cache intermediate results to avoid collecting same paths multiple times.
- match ecx.resolver.resolve_derives(ecx.current_expansion.id, derives, ecx.force_mode) {
- Ok(()) => {
- let mut visitor =
- StripUnconfigured { sess, features: ecx.ecfg.features, modified: false };
- let mut item = visitor.fully_configure(item);
- if visitor.modified {
- // Erase the tokens if cfg-stripping modified the item
- // This will cause us to synthesize fake tokens
- // when `nt_to_tokenstream` is called on this item.
- match &mut item {
- Annotatable::Item(item) => item,
- Annotatable::Stmt(stmt) => match &mut stmt.kind {
- StmtKind::Item(item) => item,
- _ => unreachable!(),
- },
- _ => unreachable!(),
- }
- .tokens = None;
- }
- ExpandResult::Ready(vec![item])
- }
- Err(Indeterminate) => ExpandResult::Retry(item),
- }
- }
-}
-
-fn report_bad_target(sess: &Session, item: &Annotatable, span: Span) -> bool {
- let item_kind = match item {
- Annotatable::Item(item) => Some(&item.kind),
- Annotatable::Stmt(stmt) => match &stmt.kind {
- StmtKind::Item(item) => Some(&item.kind),
- _ => None,
- },
- _ => None,
- };
-
- let bad_target =
- !matches!(item_kind, Some(ItemKind::Struct(..) | ItemKind::Enum(..) | ItemKind::Union(..)));
- if bad_target {
- struct_span_err!(
- sess,
- span,
- E0774,
- "`derive` may only be applied to structs, enums and unions",
- )
- .emit();
- }
- bad_target
-}
-
-fn report_unexpected_literal(sess: &Session, lit: &ast::Lit) {
- let help_msg = match lit.token.kind {
- token::Str if rustc_lexer::is_ident(&lit.token.symbol.as_str()) => {
- format!("try using `#[derive({})]`", lit.token.symbol)
- }
- _ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
- };
- struct_span_err!(sess, lit.span, E0777, "expected path to a trait, found literal",)
- .help(&help_msg)
- .emit();
-}
-
-fn report_path_args(sess: &Session, meta: &ast::MetaItem) {
- let report_error = |title, action| {
- let span = meta.span.with_lo(meta.path.span.hi());
- sess.struct_span_err(span, title)
- .span_suggestion(span, action, String::new(), Applicability::MachineApplicable)
- .emit();
- };
- match meta.kind {
- MetaItemKind::Word => {}
- MetaItemKind::List(..) => report_error(
- "traits in `#[derive(...)]` don't accept arguments",
- "remove the arguments",
- ),
- MetaItemKind::NameValue(..) => {
- report_error("traits in `#[derive(...)]` don't accept values", "remove the value")
- }
- }
-}
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index db808bf2ff51e..21174ca4c8bf9 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -1,11 +1,13 @@
+pub use OrderingOp::*;
+
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
-use crate::deriving::{path_std, pathvec_std};
+use crate::deriving::{path_local, path_std, pathvec_std};
use rustc_ast::ptr::P;
-use rustc_ast::{Expr, MetaItem};
+use rustc_ast::{self as ast, BinOpKind, Expr, MetaItem};
use rustc_expand::base::{Annotatable, ExtCtxt};
-use rustc_span::symbol::{sym, Ident};
+use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
pub fn expand_deriving_partial_ord(
@@ -15,6 +17,26 @@ pub fn expand_deriving_partial_ord(
item: &Annotatable,
push: &mut dyn FnMut(Annotatable),
) {
+ macro_rules! md {
+ ($name:expr, $op:expr, $equal:expr) => {{
+ let inline = cx.meta_word(span, sym::inline);
+ let attrs = vec![cx.attribute(inline)];
+ MethodDef {
+ name: $name,
+ generics: Bounds::empty(),
+ explicit_self: borrowed_explicit_self(),
+ args: vec![(borrowed_self(), sym::other)],
+ ret_ty: Literal(path_local!(bool)),
+ attributes: attrs,
+ is_unsafe: false,
+ unify_fieldless_variants: true,
+ combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
+ cs_op($op, $equal, cx, span, substr)
+ })),
+ }
+ }};
+ }
+
let ordering_ty = Literal(path_std!(cmp::Ordering));
let ret_ty = Literal(Path::new_(
pathvec_std!(option::Option),
@@ -40,6 +62,21 @@ pub fn expand_deriving_partial_ord(
})),
};
+ // avoid defining extra methods if we can
+ // c-like enums, enums without any fields and structs without fields
+ // can safely define only `partial_cmp`.
+ let methods = if is_type_without_fields(item) {
+ vec![partial_cmp_def]
+ } else {
+ vec![
+ partial_cmp_def,
+ md!(sym::lt, true, false),
+ md!(sym::le, true, true),
+ md!(sym::gt, false, false),
+ md!(sym::ge, false, true),
+ ]
+ };
+
let trait_def = TraitDef {
span,
attributes: vec![],
@@ -48,12 +85,39 @@ pub fn expand_deriving_partial_ord(
generics: Bounds::empty(),
is_unsafe: false,
supports_unions: false,
- methods: vec![partial_cmp_def],
+ methods,
associated_types: Vec::new(),
};
trait_def.expand(cx, mitem, item, push)
}
+#[derive(Copy, Clone)]
+pub enum OrderingOp {
+ PartialCmpOp,
+ LtOp,
+ LeOp,
+ GtOp,
+ GeOp,
+}
+
+pub fn some_ordering_collapsed(
+ cx: &mut ExtCtxt<'_>,
+ span: Span,
+ op: OrderingOp,
+ self_arg_tags: &[Ident],
+) -> P {
+ let lft = cx.expr_ident(span, self_arg_tags[0]);
+ let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
+ let op_sym = match op {
+ PartialCmpOp => sym::partial_cmp,
+ LtOp => sym::lt,
+ LeOp => sym::le,
+ GtOp => sym::gt,
+ GeOp => sym::ge,
+ };
+ cx.expr_method_call(span, lft, Ident::new(op_sym, span), vec![rgt])
+}
+
pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P {
let test_id = Ident::new(sym::cmp, span);
let ordering = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
@@ -107,9 +171,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
} else {
- let lft = cx.expr_ident(span, tag_tuple[0]);
- let rgt = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[1]));
- cx.expr_method_call(span, lft, Ident::new(sym::partial_cmp, span), vec![rgt])
+ some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
}
}),
cx,
@@ -117,3 +179,124 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
substr,
)
}
+
+/// Strict inequality.
+fn cs_op(
+ less: bool,
+ inclusive: bool,
+ cx: &mut ExtCtxt<'_>,
+ span: Span,
+ substr: &Substructure<'_>,
+) -> P {
+ let ordering_path = |cx: &mut ExtCtxt<'_>, name: &str| {
+ cx.expr_path(
+ cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, Symbol::intern(name)])),
+ )
+ };
+
+ let par_cmp = |cx: &mut ExtCtxt<'_>, span, self_f: P, other_fs: &[P], default| {
+ let other_f = match other_fs {
+ [o_f] => o_f,
+ _ => cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`"),
+ };
+
+ // `PartialOrd::partial_cmp(self.fi, other.fi)`
+ let cmp_path = cx.expr_path(
+ cx.path_global(span, cx.std_path(&[sym::cmp, sym::PartialOrd, sym::partial_cmp])),
+ );
+ let cmp = cx.expr_call(
+ span,
+ cmp_path,
+ vec![cx.expr_addr_of(span, self_f), cx.expr_addr_of(span, other_f.clone())],
+ );
+
+ let default = ordering_path(cx, default);
+ // `Option::unwrap_or(_, Ordering::Equal)`
+ let unwrap_path = cx.expr_path(
+ cx.path_global(span, cx.std_path(&[sym::option, sym::Option, sym::unwrap_or])),
+ );
+ cx.expr_call(span, unwrap_path, vec![cmp, default])
+ };
+
+ let fold = cs_fold1(
+ false, // need foldr
+ |cx, span, subexpr, self_f, other_fs| {
+ // build up a series of `partial_cmp`s from the inside
+ // out (hence foldr) to get lexical ordering, i.e., for op ==
+ // `ast::lt`
+ //
+ // ```
+ // Ordering::then_with(
+ // Option::unwrap_or(
+ // PartialOrd::partial_cmp(self.f1, other.f1), Ordering::Equal)
+ // ),
+ // Option::unwrap_or(
+ // PartialOrd::partial_cmp(self.f2, other.f2), Ordering::Greater)
+ // )
+ // )
+ // == Ordering::Less
+ // ```
+ //
+ // and for op ==
+ // `ast::le`
+ //
+ // ```
+ // Ordering::then_with(
+ // Option::unwrap_or(
+ // PartialOrd::partial_cmp(self.f1, other.f1), Ordering::Equal)
+ // ),
+ // Option::unwrap_or(
+ // PartialOrd::partial_cmp(self.f2, other.f2), Ordering::Greater)
+ // )
+ // )
+ // != Ordering::Greater
+ // ```
+ //
+ // The optimiser should remove the redundancy. We explicitly
+ // get use the binops to avoid auto-deref dereferencing too many
+ // layers of pointers, if the type includes pointers.
+
+ // `Option::unwrap_or(PartialOrd::partial_cmp(self.fi, other.fi), Ordering::Equal)`
+ let par_cmp = par_cmp(cx, span, self_f, other_fs, "Equal");
+
+ // `Ordering::then_with(Option::unwrap_or(..), ..)`
+ let then_with_path = cx.expr_path(
+ cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::then_with])),
+ );
+ cx.expr_call(span, then_with_path, vec![par_cmp, cx.lambda0(span, subexpr)])
+ },
+ |cx, args| match args {
+ Some((span, self_f, other_fs)) => {
+ let opposite = if less { "Greater" } else { "Less" };
+ par_cmp(cx, span, self_f, other_fs, opposite)
+ }
+ None => cx.expr_bool(span, inclusive),
+ },
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
+ if self_args.len() != 2 {
+ cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
+ } else {
+ let op = match (less, inclusive) {
+ (false, false) => GtOp,
+ (false, true) => GeOp,
+ (true, false) => LtOp,
+ (true, true) => LeOp,
+ };
+ some_ordering_collapsed(cx, span, op, tag_tuple)
+ }
+ }),
+ cx,
+ span,
+ substr,
+ );
+
+ match *substr.fields {
+ EnumMatching(.., ref all_fields) | Struct(.., ref all_fields) if !all_fields.is_empty() => {
+ let ordering = ordering_path(cx, if less ^ inclusive { "Less" } else { "Greater" });
+ let comp_op = if inclusive { BinOpKind::Ne } else { BinOpKind::Eq };
+
+ cx.expr_binary(span, comp_op, fold, ordering)
+ }
+ _ => fold,
+ }
+}
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index ba43be6ae9a9e..5c21329069bfc 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -8,10 +8,6 @@ use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, DUMMY_SP};
-fn make_mut_borrow(cx: &mut ExtCtxt<'_>, sp: Span, expr: P) -> P {
- cx.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Mut, expr))
-}
-
pub fn expand_deriving_debug(
cx: &mut ExtCtxt<'_>,
span: Span,
@@ -71,12 +67,11 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
let fmt = substr.nonself_args[0].clone();
let mut stmts = Vec::with_capacity(fields.len() + 2);
- let fn_path_finish;
match vdata {
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
// tuple struct/"normal" variant
- let fn_path_debug_tuple = cx.std_path(&[sym::fmt, sym::Formatter, sym::debug_tuple]);
- let expr = cx.expr_call_global(span, fn_path_debug_tuple, vec![fmt, name]);
+ let expr =
+ cx.expr_method_call(span, fmt, Ident::new(sym::debug_tuple, span), vec![name]);
stmts.push(cx.stmt_let(span, true, builder, expr));
for field in fields {
@@ -84,21 +79,22 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
let field = cx.expr_addr_of(field.span, field.self_.clone());
let field = cx.expr_addr_of(field.span, field);
- let fn_path_field = cx.std_path(&[sym::fmt, sym::DebugTuple, sym::field]);
- let builder_recv = make_mut_borrow(cx, span, builder_expr.clone());
- let expr = cx.expr_call_global(span, fn_path_field, vec![builder_recv, field]);
+ let expr = cx.expr_method_call(
+ span,
+ builder_expr.clone(),
+ Ident::new(sym::field, span),
+ vec![field],
+ );
// Use `let _ = expr;` to avoid triggering the
// unused_results lint.
stmts.push(stmt_let_underscore(cx, span, expr));
}
-
- fn_path_finish = cx.std_path(&[sym::fmt, sym::DebugTuple, sym::finish]);
}
ast::VariantData::Struct(..) => {
// normal struct/struct variant
- let fn_path_debug_struct = cx.std_path(&[sym::fmt, sym::Formatter, sym::debug_struct]);
- let expr = cx.expr_call_global(span, fn_path_debug_struct, vec![fmt, name]);
+ let expr =
+ cx.expr_method_call(span, fmt, Ident::new(sym::debug_struct, span), vec![name]);
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
for field in fields {
@@ -108,20 +104,20 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
);
// Use double indirection to make sure this works for unsized types
- let fn_path_field = cx.std_path(&[sym::fmt, sym::DebugStruct, sym::field]);
let field = cx.expr_addr_of(field.span, field.self_.clone());
let field = cx.expr_addr_of(field.span, field);
- let builder_recv = make_mut_borrow(cx, span, builder_expr.clone());
- let expr =
- cx.expr_call_global(span, fn_path_field, vec![builder_recv, name, field]);
+ let expr = cx.expr_method_call(
+ span,
+ builder_expr.clone(),
+ Ident::new(sym::field, span),
+ vec![name, field],
+ );
stmts.push(stmt_let_underscore(cx, span, expr));
}
- fn_path_finish = cx.std_path(&[sym::fmt, sym::DebugStruct, sym::finish]);
}
}
- let builder_recv = make_mut_borrow(cx, span, builder_expr);
- let expr = cx.expr_call_global(span, fn_path_finish, vec![builder_recv]);
+ let expr = cx.expr_method_call(span, builder_expr, Ident::new(sym::finish, span), vec![]);
stmts.push(cx.stmt_expr(expr));
let block = cx.block(span, stmts);
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index d498c8e172799..e78d1368b357e 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -527,12 +527,12 @@ impl<'a> TraitDef<'a> {
tokens: None,
},
attrs: Vec::new(),
- kind: ast::AssocItemKind::TyAlias(box ast::TyAliasKind(
+ kind: ast::AssocItemKind::TyAlias(
ast::Defaultness::Final,
Generics::default(),
Vec::new(),
Some(type_def.to_ty(cx, self.span, type_ident, generics)),
- )),
+ ),
tokens: None,
})
});
@@ -598,7 +598,7 @@ impl<'a> TraitDef<'a> {
let mut ty_params = params
.iter()
- .filter(|param| matches!(param.kind, ast::GenericParamKind::Type { .. }))
+ .filter(|param| matches!(param.kind, ast::GenericParamKind::Type{..}))
.peekable();
if ty_params.peek().is_some() {
@@ -687,7 +687,7 @@ impl<'a> TraitDef<'a> {
self.span,
Ident::invalid(),
a,
- ast::ItemKind::Impl(box ast::ImplKind {
+ ast::ItemKind::Impl {
unsafety,
polarity: ast::ImplPolarity::Positive,
defaultness: ast::Defaultness::Final,
@@ -696,7 +696,7 @@ impl<'a> TraitDef<'a> {
of_trait: opt_trait_ref,
self_ty: self_type,
items: methods.into_iter().chain(associated_types).collect(),
- }),
+ },
)
}
@@ -929,7 +929,7 @@ impl<'a> MethodDef<'a> {
tokens: None,
},
ident: method_ident,
- kind: ast::AssocItemKind::Fn(box ast::FnKind(def, sig, fn_generics, Some(body_block))),
+ kind: ast::AssocItemKind::Fn(def, sig, fn_generics, Some(body_block)),
tokens: None,
})
}
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index 7dea6099f8f1b..3c8bf12b3d415 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -2,7 +2,7 @@
use rustc_ast as ast;
use rustc_ast::ptr::P;
-use rustc_ast::{ImplKind, ItemKind, MetaItem};
+use rustc_ast::{ItemKind, MetaItem};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
@@ -179,7 +179,7 @@ fn inject_impl_of_structural_trait(
span,
Ident::invalid(),
attrs,
- ItemKind::Impl(box ImplKind {
+ ItemKind::Impl {
unsafety: ast::Unsafe::No,
polarity: ast::ImplPolarity::Positive,
defaultness: ast::Defaultness::Final,
@@ -188,7 +188,7 @@ fn inject_impl_of_structural_trait(
of_trait: Some(trait_ref),
self_ty: self_type,
items: Vec::new(),
- }),
+ },
);
push(Annotatable::Item(newitem));
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index 9b43c11f0f3d3..e976805d9dd20 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -5,7 +5,7 @@ use rustc_ast::expand::allocator::{
};
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
-use rustc_ast::{FnKind, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
+use rustc_ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
@@ -85,8 +85,7 @@ impl AllocFnFactory<'_, '_> {
let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() };
let sig = FnSig { decl, header, span: self.span };
let block = Some(self.cx.block_expr(output_expr));
- let kind =
- ItemKind::Fn(box FnKind(ast::Defaultness::Final, sig, Generics::default(), block));
+ let kind = ItemKind::Fn(ast::Defaultness::Final, sig, Generics::default(), block);
let item = self.cx.item(
self.span,
Ident::from_str_and_span(&self.kind.fn_name(method.name), self.span),
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 9a3c914337ca2..bcb3622a95980 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -2,8 +2,6 @@
//! injecting code into the crate before it is lowered to HIR.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![feature(box_patterns)]
-#![feature(box_syntax)]
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(decl_macro)]
@@ -27,7 +25,6 @@ mod cfg_accessible;
mod compile_error;
mod concat;
mod concat_idents;
-mod derive;
mod deriving;
mod env;
mod format;
@@ -89,7 +86,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
register_attr! {
bench: test::expand_bench,
cfg_accessible: cfg_accessible::Expander,
- derive: derive::Expander,
global_allocator: global_allocator::expand,
test: test::expand_test,
test_case: test::expand_test_case,
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index e845f9ec55ad5..25d3f46da6cdc 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -425,7 +425,7 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
let has_should_panic_attr = cx.sess.contains_name(&i.attrs, sym::should_panic);
let sd = &cx.sess.parse_sess.span_diagnostic;
- if let ast::ItemKind::Fn(box ast::FnKind(_, ref sig, ref generics, _)) = i.kind {
+ if let ast::ItemKind::Fn(_, ref sig, ref generics, _) = i.kind {
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
.span_label(span, "`unsafe` because of this")
@@ -474,7 +474,7 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
}
fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
- let has_sig = if let ast::ItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) = i.kind {
+ let has_sig = if let ast::ItemKind::Fn(_, ref sig, _, _) = i.kind {
// N.B., inadequate check, but we're running
// well before resolve, can't get too deep.
sig.decl.inputs.len() == 1
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 4ac22be3c275d..9976140d6bd8c 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -311,8 +311,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P {
let decl = ecx.fn_decl(vec![], ast::FnRetTy::Ty(main_ret_ty));
let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
let def = ast::Defaultness::Final;
- let main =
- ast::ItemKind::Fn(box ast::FnKind(def, sig, ast::Generics::default(), Some(main_body)));
+ let main = ast::ItemKind::Fn(def, sig, ast::Generics::default(), Some(main_body));
// Honor the reexport_test_harness_main attribute
let main_id = match cx.reexport_test_harness_main {
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index b2647e6c8d384..6a025f2e88ae3 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -28,7 +28,6 @@ fn clif_sig_from_fn_abi<'tcx>(
Conv::X86_64SysV => CallConv::SystemV,
Conv::X86_64Win64 => CallConv::WindowsFastcall,
Conv::ArmAapcs
- | Conv::CCmseNonSecureCall
| Conv::Msp430Intr
| Conv::PtxKernel
| Conv::X86Fastcall
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index a69241e456f16..915dd3d9eda15 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -389,7 +389,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
fn llvm_cconv(&self) -> llvm::CallConv {
match self.conv {
- Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
+ Conv::C | Conv::Rust => llvm::CCallConv,
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
Conv::AvrInterrupt => llvm::AvrInterrupt,
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
@@ -546,18 +546,6 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
if cconv != llvm::CCallConv {
llvm::SetInstructionCallConv(callsite, cconv);
}
-
- if self.conv == Conv::CCmseNonSecureCall {
- // This will probably get ignored on all targets but those supporting the TrustZone-M
- // extension (thumbv8m targets).
- unsafe {
- llvm::AddCallSiteAttrString(
- callsite,
- llvm::AttributePlace::Function,
- rustc_data_structures::const_cstr!("cmse_nonsecure_call"),
- );
- }
- }
}
}
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index 16e1a8a1242ae..14dd245625d25 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -8,7 +8,9 @@ use crate::value::Value;
use libc::c_uint;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::const_cstr;
+use rustc_hir as hir;
use rustc_hir::def_id::DefId;
+use rustc_hir::Node;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::interpret::{
read_target_uint, Allocation, ErrorHandled, GlobalAlloc, Pointer,
@@ -16,6 +18,7 @@ use rustc_middle::mir::interpret::{
use rustc_middle::mir::mono::MonoItem;
use rustc_middle::ty::{self, Instance, Ty};
use rustc_middle::{bug, span_bug};
+use rustc_span::symbol::sym;
use rustc_target::abi::{AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size};
use tracing::debug;
@@ -206,42 +209,70 @@ impl CodegenCx<'ll, 'tcx> {
let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all());
let sym = self.tcx.symbol_name(instance).name;
- let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
- debug!("get_static: sym={} instance={:?} fn_attrs={:?}", sym, instance, fn_attrs);
+ debug!("get_static: sym={} instance={:?}", sym, instance);
- let g = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) {
+ let g = if let Some(local_def_id) = def_id.as_local() {
+ let id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
let llty = self.layout_of(ty).llvm_type(self);
- if let Some(g) = self.get_declared_value(sym) {
- if self.val_ty(g) != self.type_ptr_to(llty) {
- span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
+ // FIXME: refactor this to work without accessing the HIR
+ let (g, attrs) = match self.tcx.hir().get(id) {
+ Node::Item(&hir::Item { attrs, kind: hir::ItemKind::Static(..), .. }) => {
+ if let Some(g) = self.get_declared_value(sym) {
+ if self.val_ty(g) != self.type_ptr_to(llty) {
+ span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
+ }
+ }
+
+ let g = self.declare_global(sym, llty);
+
+ if !self.tcx.is_reachable_non_generic(local_def_id) {
+ unsafe {
+ llvm::LLVMRustSetVisibility(g, llvm::Visibility::Hidden);
+ }
+ }
+
+ (g, attrs)
}
- }
- let g = self.declare_global(sym, llty);
+ Node::ForeignItem(&hir::ForeignItem {
+ ref attrs,
+ kind: hir::ForeignItemKind::Static(..),
+ ..
+ }) => {
+ let fn_attrs = self.tcx.codegen_fn_attrs(local_def_id);
+ (check_and_apply_linkage(&self, &fn_attrs, ty, sym, def_id), &**attrs)
+ }
+
+ item => bug!("get_static: expected static, found {:?}", item),
+ };
+
+ debug!("get_static: sym={} attrs={:?}", sym, attrs);
- if !self.tcx.is_reachable_non_generic(def_id) {
- unsafe {
- llvm::LLVMRustSetVisibility(g, llvm::Visibility::Hidden);
+ for attr in attrs {
+ if self.tcx.sess.check_name(attr, sym::thread_local) {
+ llvm::set_thread_local_mode(g, self.tls_model);
}
}
g
} else {
- check_and_apply_linkage(&self, &fn_attrs, ty, sym, def_id)
- };
+ // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
+ debug!("get_static: sym={} item_attr={:?}", sym, self.tcx.item_attrs(def_id));
- // Thread-local statics in some other crate need to *always* be linked
- // against in a thread-local fashion, so we need to be sure to apply the
- // thread-local attribute locally if it was present remotely. If we
- // don't do this then linker errors can be generated where the linker
- // complains that one object files has a thread local version of the
- // symbol and another one doesn't.
- if fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
- llvm::set_thread_local_mode(g, self.tls_model);
- }
+ let attrs = self.tcx.codegen_fn_attrs(def_id);
+ let g = check_and_apply_linkage(&self, &attrs, ty, sym, def_id);
+
+ // Thread-local statics in some other crate need to *always* be linked
+ // against in a thread-local fashion, so we need to be sure to apply the
+ // thread-local attribute locally if it was present remotely. If we
+ // don't do this then linker errors can be generated where the linker
+ // complains that one object files has a thread local version of the
+ // symbol and another one doesn't.
+ if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
+ llvm::set_thread_local_mode(g, self.tls_model);
+ }
- if !def_id.is_local() {
let needs_dll_storage_attr = self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) &&
// ThinLTO can't handle this workaround in all cases, so we don't
// emit the attrs. Instead we make them unnecessary by disallowing
@@ -273,7 +304,8 @@ impl CodegenCx<'ll, 'tcx> {
}
}
}
- }
+ g
+ };
if self.use_dll_storage_attrs && self.tcx.is_dllimport_foreign_item(def_id) {
// For foreign (native) libs we know the exact storage type to use.
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index ee099f93258b7..6acd26bd415dc 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -380,7 +380,7 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
"rust_eh_personality"
};
let fty = self.type_variadic_func(&[], self.type_i32());
- self.declare_cfn(name, llvm::UnnamedAddr::Global, fty)
+ self.declare_cfn(name, fty)
}
};
attributes::apply_target_cpu_attr(self, llfn);
@@ -429,7 +429,7 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn declare_c_main(&self, fn_type: Self::Type) -> Option {
if self.get_declared_value("main").is_none() {
- Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type))
+ Some(self.declare_cfn("main", fn_type))
} else {
// If the symbol already exists, it is an error: for example, the user wrote
// #[no_mangle] extern "C" fn main(..) {..}
@@ -459,7 +459,8 @@ impl CodegenCx<'b, 'tcx> {
} else {
self.type_variadic_func(&[], ret)
};
- let f = self.declare_cfn(name, llvm::UnnamedAddr::No, fn_ty);
+ let f = self.declare_cfn(name, fn_ty);
+ llvm::SetUnnamedAddress(f, llvm::UnnamedAddr::No);
self.intrinsics.borrow_mut().insert(name, f);
f
}
@@ -497,6 +498,25 @@ impl CodegenCx<'b, 'tcx> {
let t_f32 = self.type_f32();
let t_f64 = self.type_f64();
+ macro_rules! vector_types {
+ ($id_out:ident: $elem_ty:ident, $len:expr) => {
+ let $id_out = self.type_vector($elem_ty, $len);
+ };
+ ($($id_out:ident: $elem_ty:ident, $len:expr;)*) => {
+ $(vector_types!($id_out: $elem_ty, $len);)*
+ }
+ }
+ vector_types! {
+ t_v2f32: t_f32, 2;
+ t_v4f32: t_f32, 4;
+ t_v8f32: t_f32, 8;
+ t_v16f32: t_f32, 16;
+
+ t_v2f64: t_f64, 2;
+ t_v4f64: t_f64, 4;
+ t_v8f64: t_f64, 8;
+ }
+
ifn!("llvm.wasm.trunc.saturate.unsigned.i32.f32", fn(t_f32) -> t_i32);
ifn!("llvm.wasm.trunc.saturate.unsigned.i32.f64", fn(t_f64) -> t_i32);
ifn!("llvm.wasm.trunc.saturate.unsigned.i64.f32", fn(t_f32) -> t_i64);
@@ -520,40 +540,124 @@ impl CodegenCx<'b, 'tcx> {
ifn!("llvm.sideeffect", fn() -> void);
ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
+ ifn!("llvm.powi.v2f32", fn(t_v2f32, t_i32) -> t_v2f32);
+ ifn!("llvm.powi.v4f32", fn(t_v4f32, t_i32) -> t_v4f32);
+ ifn!("llvm.powi.v8f32", fn(t_v8f32, t_i32) -> t_v8f32);
+ ifn!("llvm.powi.v16f32", fn(t_v16f32, t_i32) -> t_v16f32);
ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
+ ifn!("llvm.powi.v2f64", fn(t_v2f64, t_i32) -> t_v2f64);
+ ifn!("llvm.powi.v4f64", fn(t_v4f64, t_i32) -> t_v4f64);
+ ifn!("llvm.powi.v8f64", fn(t_v8f64, t_i32) -> t_v8f64);
ifn!("llvm.pow.f32", fn(t_f32, t_f32) -> t_f32);
+ ifn!("llvm.pow.v2f32", fn(t_v2f32, t_v2f32) -> t_v2f32);
+ ifn!("llvm.pow.v4f32", fn(t_v4f32, t_v4f32) -> t_v4f32);
+ ifn!("llvm.pow.v8f32", fn(t_v8f32, t_v8f32) -> t_v8f32);
+ ifn!("llvm.pow.v16f32", fn(t_v16f32, t_v16f32) -> t_v16f32);
ifn!("llvm.pow.f64", fn(t_f64, t_f64) -> t_f64);
+ ifn!("llvm.pow.v2f64", fn(t_v2f64, t_v2f64) -> t_v2f64);
+ ifn!("llvm.pow.v4f64", fn(t_v4f64, t_v4f64) -> t_v4f64);
+ ifn!("llvm.pow.v8f64", fn(t_v8f64, t_v8f64) -> t_v8f64);
ifn!("llvm.sqrt.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.sqrt.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.sqrt.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.sqrt.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.sqrt.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.sqrt.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.sqrt.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.sqrt.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.sqrt.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.sin.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.sin.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.sin.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.sin.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.sin.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.sin.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.sin.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.sin.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.sin.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.cos.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.cos.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.cos.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.cos.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.cos.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.cos.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.cos.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.cos.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.cos.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.exp.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.exp.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.exp.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.exp.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.exp.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.exp.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.exp.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.exp.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.exp.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.exp2.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.exp2.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.exp2.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.exp2.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.exp2.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.exp2.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.exp2.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.exp2.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.exp2.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.log.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.log.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.log.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.log.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.log.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.log.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.log.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.log.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.log.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.log10.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.log10.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.log10.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.log10.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.log10.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.log10.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.log10.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.log10.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.log10.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.log2.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.log2.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.log2.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.log2.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.log2.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.log2.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.log2.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.log2.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.log2.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.fma.f32", fn(t_f32, t_f32, t_f32) -> t_f32);
+ ifn!("llvm.fma.v2f32", fn(t_v2f32, t_v2f32, t_v2f32) -> t_v2f32);
+ ifn!("llvm.fma.v4f32", fn(t_v4f32, t_v4f32, t_v4f32) -> t_v4f32);
+ ifn!("llvm.fma.v8f32", fn(t_v8f32, t_v8f32, t_v8f32) -> t_v8f32);
+ ifn!("llvm.fma.v16f32", fn(t_v16f32, t_v16f32, t_v16f32) -> t_v16f32);
ifn!("llvm.fma.f64", fn(t_f64, t_f64, t_f64) -> t_f64);
+ ifn!("llvm.fma.v2f64", fn(t_v2f64, t_v2f64, t_v2f64) -> t_v2f64);
+ ifn!("llvm.fma.v4f64", fn(t_v4f64, t_v4f64, t_v4f64) -> t_v4f64);
+ ifn!("llvm.fma.v8f64", fn(t_v8f64, t_v8f64, t_v8f64) -> t_v8f64);
ifn!("llvm.fabs.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.fabs.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.fabs.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.fabs.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.fabs.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.fabs.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.fabs.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.fabs.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.fabs.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.minnum.f32", fn(t_f32, t_f32) -> t_f32);
ifn!("llvm.minnum.f64", fn(t_f64, t_f64) -> t_f64);
@@ -561,10 +665,24 @@ impl CodegenCx<'b, 'tcx> {
ifn!("llvm.maxnum.f64", fn(t_f64, t_f64) -> t_f64);
ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.floor.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.floor.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.floor.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.floor.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.floor.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.floor.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.floor.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.floor.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.ceil.f32", fn(t_f32) -> t_f32);
+ ifn!("llvm.ceil.v2f32", fn(t_v2f32) -> t_v2f32);
+ ifn!("llvm.ceil.v4f32", fn(t_v4f32) -> t_v4f32);
+ ifn!("llvm.ceil.v8f32", fn(t_v8f32) -> t_v8f32);
+ ifn!("llvm.ceil.v16f32", fn(t_v16f32) -> t_v16f32);
ifn!("llvm.ceil.f64", fn(t_f64) -> t_f64);
+ ifn!("llvm.ceil.v2f64", fn(t_v2f64) -> t_v2f64);
+ ifn!("llvm.ceil.v4f64", fn(t_v4f64) -> t_v4f64);
+ ifn!("llvm.ceil.v8f64", fn(t_v8f64) -> t_v8f64);
ifn!("llvm.trunc.f32", fn(t_f32) -> t_f32);
ifn!("llvm.trunc.f64", fn(t_f64) -> t_f64);
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index 8977fa085b9bb..0591e0a5c1279 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -30,7 +30,6 @@ fn declare_raw_fn(
cx: &CodegenCx<'ll, '_>,
name: &str,
callconv: llvm::CallConv,
- unnamed: llvm::UnnamedAddr,
ty: &'ll Type,
) -> &'ll Value {
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
@@ -39,7 +38,9 @@ fn declare_raw_fn(
};
llvm::SetFunctionCallConv(llfn, callconv);
- llvm::SetUnnamedAddress(llfn, unnamed);
+ // Function addresses in Rust are never significant, allowing functions to
+ // be merged.
+ llvm::SetUnnamedAddress(llfn, llvm::UnnamedAddr::Global);
if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.disable_redzone) {
llvm::Attribute::NoRedZone.apply_llfn(Function, llfn);
@@ -67,13 +68,8 @@ impl CodegenCx<'ll, 'tcx> {
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
- pub fn declare_cfn(
- &self,
- name: &str,
- unnamed: llvm::UnnamedAddr,
- fn_type: &'ll Type,
- ) -> &'ll Value {
- declare_raw_fn(self, name, llvm::CCallConv, unnamed, fn_type)
+ pub fn declare_cfn(&self, name: &str, fn_type: &'ll Type) -> &'ll Value {
+ declare_raw_fn(self, name, llvm::CCallConv, fn_type)
}
/// Declare a Rust function.
@@ -83,15 +79,7 @@ impl CodegenCx<'ll, 'tcx> {
pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value {
debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi);
- // Function addresses in Rust are never significant, allowing functions to
- // be merged.
- let llfn = declare_raw_fn(
- self,
- name,
- fn_abi.llvm_cconv(),
- llvm::UnnamedAddr::Global,
- fn_abi.llvm_type(self),
- );
+ let llfn = declare_raw_fn(self, name, fn_abi.llvm_cconv(), fn_abi.llvm_type(self));
fn_abi.apply_attrs_llfn(self, llfn);
llfn
}
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 668daa52ed262..bf0d499e6c491 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1009,7 +1009,7 @@ fn generic_simd_intrinsic(
}
fn simd_simple_float_intrinsic(
- name: Symbol,
+ name: &str,
in_elem: &::rustc_middle::ty::TyS<'_>,
in_ty: &::rustc_middle::ty::TyS<'_>,
in_len: u64,
@@ -1036,69 +1036,93 @@ fn generic_simd_intrinsic(
}
}
}
-
- let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() {
- let elem_ty = bx.cx.type_float_from_ty(*f);
- match f.bit_width() {
- 32 => ("f32", elem_ty),
- 64 => ("f64", elem_ty),
- _ => {
+ let ety = match in_elem.kind() {
+ ty::Float(f) if f.bit_width() == 32 => {
+ if in_len < 2 || in_len > 16 {
return_error!(
- "unsupported element type `{}` of floating-point vector `{}`",
- f.name_str(),
- in_ty
+ "unsupported floating-point vector `{}` with length `{}` \
+ out-of-range [2, 16]",
+ in_ty,
+ in_len
);
}
+ "f32"
+ }
+ ty::Float(f) if f.bit_width() == 64 => {
+ if in_len < 2 || in_len > 8 {
+ return_error!(
+ "unsupported floating-point vector `{}` with length `{}` \
+ out-of-range [2, 8]",
+ in_ty,
+ in_len
+ );
+ }
+ "f64"
+ }
+ ty::Float(f) => {
+ return_error!(
+ "unsupported element type `{}` of floating-point vector `{}`",
+ f.name_str(),
+ in_ty
+ );
+ }
+ _ => {
+ return_error!("`{}` is not a floating-point type", in_ty);
}
- } else {
- return_error!("`{}` is not a floating-point type", in_ty);
- };
-
- let vec_ty = bx.type_vector(elem_ty, in_len);
-
- let (intr_name, fn_ty) = match name {
- sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_fcos => ("cos", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_fabs => ("fabs", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_ceil => ("ceil", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_fexp => ("exp", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_fexp2 => ("exp2", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_flog10 => ("log10", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_flog2 => ("log2", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_flog => ("log", bx.type_func(&[vec_ty], vec_ty)),
- sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)),
- sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)),
- sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)),
- _ => return_error!("unrecognized intrinsic `{}`", name),
};
- let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
- let f = bx.declare_cfn(&llvm_name, llvm::UnnamedAddr::No, fn_ty);
- let c = bx.call(f, &args.iter().map(|arg| arg.immediate()).collect::>(), None);
+ let llvm_name = &format!("llvm.{0}.v{1}{2}", name, in_len, ety);
+ let intrinsic = bx.get_intrinsic(&llvm_name);
+ let c =
+ bx.call(intrinsic, &args.iter().map(|arg| arg.immediate()).collect::>(), None);
unsafe { llvm::LLVMRustSetHasUnsafeAlgebra(c) };
Ok(c)
}
- if std::matches!(
- name,
- sym::simd_fsqrt
- | sym::simd_fsin
- | sym::simd_fcos
- | sym::simd_fabs
- | sym::simd_floor
- | sym::simd_ceil
- | sym::simd_fexp
- | sym::simd_fexp2
- | sym::simd_flog10
- | sym::simd_flog2
- | sym::simd_flog
- | sym::simd_fpowi
- | sym::simd_fpow
- | sym::simd_fma
- ) {
- return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args);
+ match name {
+ sym::simd_fsqrt => {
+ return simd_simple_float_intrinsic("sqrt", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_fsin => {
+ return simd_simple_float_intrinsic("sin", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_fcos => {
+ return simd_simple_float_intrinsic("cos", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_fabs => {
+ return simd_simple_float_intrinsic("fabs", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_floor => {
+ return simd_simple_float_intrinsic("floor", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_ceil => {
+ return simd_simple_float_intrinsic("ceil", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_fexp => {
+ return simd_simple_float_intrinsic("exp", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_fexp2 => {
+ return simd_simple_float_intrinsic("exp2", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_flog10 => {
+ return simd_simple_float_intrinsic("log10", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_flog2 => {
+ return simd_simple_float_intrinsic("log2", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_flog => {
+ return simd_simple_float_intrinsic("log", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_fpowi => {
+ return simd_simple_float_intrinsic("powi", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_fpow => {
+ return simd_simple_float_intrinsic("pow", in_elem, in_ty, in_len, bx, span, args);
+ }
+ sym::simd_fma => {
+ return simd_simple_float_intrinsic("fma", in_elem, in_ty, in_len, bx, span, args);
+ }
+ _ => { /* fallthrough */ }
}
// FIXME: use:
@@ -1254,12 +1278,12 @@ fn generic_simd_intrinsic(
format!("llvm.masked.gather.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);
let f = bx.declare_cfn(
&llvm_intrinsic,
- llvm::UnnamedAddr::No,
bx.type_func(
&[llvm_pointer_vec_ty, alignment_ty, mask_ty, llvm_elem_vec_ty],
llvm_elem_vec_ty,
),
);
+ llvm::SetUnnamedAddress(f, llvm::UnnamedAddr::No);
let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None);
return Ok(v);
}
@@ -1384,9 +1408,9 @@ fn generic_simd_intrinsic(
format!("llvm.masked.scatter.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str);
let f = bx.declare_cfn(
&llvm_intrinsic,
- llvm::UnnamedAddr::No,
bx.type_func(&[llvm_elem_vec_ty, llvm_pointer_vec_ty, alignment_ty, mask_ty], ret_t),
);
+ llvm::SetUnnamedAddress(f, llvm::UnnamedAddr::No);
let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None);
return Ok(v);
}
@@ -1690,11 +1714,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
);
let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64);
- let f = bx.declare_cfn(
- &llvm_intrinsic,
- llvm::UnnamedAddr::No,
- bx.type_func(&[vec_ty, vec_ty], vec_ty),
- );
+ let f = bx.declare_cfn(&llvm_intrinsic, bx.type_func(&[vec_ty, vec_ty], vec_ty));
+ llvm::SetUnnamedAddress(f, llvm::UnnamedAddr::No);
let v = bx.call(f, &[lhs, rhs], None);
return Ok(v);
}
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index e82198f8f0c06..d9f42efebab47 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1100,7 +1100,6 @@ extern "C" {
// Operations on call sites
pub fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint);
pub fn LLVMRustAddCallSiteAttribute(Instr: &Value, index: c_uint, attr: Attribute);
- pub fn LLVMRustAddCallSiteAttrString(Instr: &Value, index: c_uint, Name: *const c_char);
pub fn LLVMRustAddAlignmentCallSiteAttr(Instr: &Value, index: c_uint, bytes: u32);
pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64);
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index bb9c6d47373ba..fc40065a9664e 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -43,10 +43,6 @@ pub fn AddFunctionAttrString(llfn: &'a Value, idx: AttributePlace, attr: &CStr)
}
}
-pub fn AddCallSiteAttrString(callsite: &Value, idx: AttributePlace, attr: &CStr) {
- unsafe { LLVMRustAddCallSiteAttrString(callsite, idx.as_uint(), attr.as_ptr()) }
-}
-
#[derive(Copy, Clone)]
pub enum AttributePlace {
ReturnValue,
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index 39d08fbee3b7f..07fde27b5a314 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -105,6 +105,7 @@ fn emit_aapcs_va_arg(
let mut end = bx.build_sibling_block("va_arg.end");
let zero = bx.const_i32(0);
let offset_align = Align::from_bytes(4).unwrap();
+ assert_eq!(bx.tcx().sess.target.endian, Endian::Little);
let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
let (reg_off, reg_top_index, slot_size) = if gr_type {
@@ -143,14 +144,9 @@ fn emit_aapcs_va_arg(
let top = in_reg.load(top, bx.tcx().data_layout.pointer_align.abi);
// reg_value = *(@top + reg_off_v);
- let mut reg_addr = in_reg.gep(top, &[reg_off_v]);
- if bx.tcx().sess.target.endian == Endian::Big && layout.size.bytes() != slot_size {
- // On big-endian systems the value is right-aligned in its slot.
- let offset = bx.const_i32((slot_size - layout.size.bytes()) as i32);
- reg_addr = in_reg.gep(reg_addr, &[offset]);
- }
- let reg_addr = in_reg.bitcast(reg_addr, bx.cx.type_ptr_to(layout.llvm_type(bx)));
- let reg_value = in_reg.load(reg_addr, layout.align.abi);
+ let top = in_reg.gep(top, &[reg_off_v]);
+ let top = in_reg.bitcast(top, bx.cx.type_ptr_to(layout.llvm_type(bx)));
+ let reg_value = in_reg.load(top, layout.align.abi);
in_reg.br(&end.llbb());
// On Stack block
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 835f906239953..e5df0f60941a8 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -10,7 +10,6 @@ test = false
[dependencies]
bitflags = "1.2.1"
cc = "1.0.1"
-itertools = "0.9"
num_cpus = "1.0"
memmap = "0.7"
tracing = "0.1"
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 658ad3c375d29..0fc11c286f899 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -32,11 +32,10 @@ use rustc_session::config::{self, EntryFnType};
use rustc_session::Session;
use rustc_target::abi::{Align, LayoutOf, VariantIdx};
+use std::cmp;
use std::ops::{Deref, DerefMut};
use std::time::{Duration, Instant};
-use itertools::Itertools;
-
pub fn bin_op_to_icmp_predicate(op: hir::BinOpKind, signed: bool) -> IntPredicate {
match op {
hir::BinOpKind::Eq => IntPredicate::IntEQ,
@@ -547,23 +546,12 @@ pub fn codegen_crate(
ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, metadata_module);
}
- // For better throughput during parallel processing by LLVM, we used to sort
- // CGUs largest to smallest. This would lead to better thread utilization
- // by, for example, preventing a large CGU from being processed last and
- // having only one LLVM thread working while the rest remained idle.
- //
- // However, this strategy would lead to high memory usage, as it meant the
- // LLVM-IR for all of the largest CGUs would be resident in memory at once.
- //
- // Instead, we can compromise by ordering CGUs such that the largest and
- // smallest are first, second largest and smallest are next, etc. If there
- // are large size variations, this can reduce memory usage significantly.
- let codegen_units: Vec<_> = {
- let mut sorted_cgus = codegen_units.iter().collect::>();
- sorted_cgus.sort_by_cached_key(|cgu| cgu.size_estimate());
-
- let (first_half, second_half) = sorted_cgus.split_at(sorted_cgus.len() / 2);
- second_half.iter().rev().interleave(first_half).copied().collect()
+ // We sort the codegen units by size. This way we can schedule work for LLVM
+ // a bit more efficiently.
+ let codegen_units = {
+ let mut codegen_units = codegen_units.iter().collect::>();
+ codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
+ codegen_units
};
// The non-parallel compiler can only translate codegen units to LLVM IR
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 5880bbd3de44e..36d261fb737ce 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -13,7 +13,6 @@
#![feature(unboxed_closures)]
#![feature(generator_trait)]
#![feature(fn_traits)]
-#![feature(int_bits_const)]
#![feature(min_specialization)]
#![feature(auto_traits)]
#![feature(nll)]
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index f0b413c795e9c..9a85b9d02c995 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -590,21 +590,24 @@ pub fn print_time_passes_entry(
end_rss: Option,
) {
let rss_to_mb = |rss| (rss as f64 / 1_000_000.0).round() as usize;
- let rss_change_to_mb = |rss| (rss as f64 / 1_000_000.0).round() as i128;
let mem_string = match (start_rss, end_rss) {
(Some(start_rss), Some(end_rss)) => {
- let change_rss = end_rss as i128 - start_rss as i128;
-
- format!(
- "; rss: {:>4}MB -> {:>4}MB ({:>+5}MB)",
- rss_to_mb(start_rss),
- rss_to_mb(end_rss),
- rss_change_to_mb(change_rss),
- )
+ // It's tempting to add the change in RSS from start to end, but its somewhat confusing
+ // and misleading when looking at time-passes output. Consider two adjacent entries:
+ //
+ // time: 10.000; rss start: 1000MB, end: 1000MB, change: 0MB pass1
+ // time: 5.000; rss start: 2000MB, end: 2000MB, change: 0MB pass2
+ //
+ // If you're looking for jumps in RSS based on the change column, you miss the fact
+ // that a 1GB jump happened between pass1 and pass2 (supposing pass1 and pass2 actually
+ // occur sequentially and pass1 isn't just nested within pass2). It's easy to imagine
+ // someone missing this or being confused by the fact that the change is zero.
+
+ format!("; rss: {:>5}MB -> {:>5}MB", rss_to_mb(start_rss), rss_to_mb(end_rss))
}
- (Some(start_rss), None) => format!("; rss start: {:>4}MB", rss_to_mb(start_rss)),
- (None, Some(end_rss)) => format!("; rss end: {:>4}MB", rss_to_mb(end_rss)),
+ (Some(start_rss), None) => format!("; rss start: {:>5}MB", rss_to_mb(start_rss)),
+ (None, Some(end_rss)) => format!("; rss end: {:5>}MB", rss_to_mb(end_rss)),
(None, None) => String::new(),
};
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 849ef18fb90cb..c669f7fed272a 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -267,7 +267,6 @@ E0516: include_str!("./error_codes/E0516.md"),
E0517: include_str!("./error_codes/E0517.md"),
E0518: include_str!("./error_codes/E0518.md"),
E0520: include_str!("./error_codes/E0520.md"),
-E0521: include_str!("./error_codes/E0521.md"),
E0522: include_str!("./error_codes/E0522.md"),
E0524: include_str!("./error_codes/E0524.md"),
E0525: include_str!("./error_codes/E0525.md"),
@@ -285,7 +284,6 @@ E0537: include_str!("./error_codes/E0537.md"),
E0538: include_str!("./error_codes/E0538.md"),
E0539: include_str!("./error_codes/E0539.md"),
E0541: include_str!("./error_codes/E0541.md"),
-E0542: include_str!("./error_codes/E0542.md"),
E0546: include_str!("./error_codes/E0546.md"),
E0550: include_str!("./error_codes/E0550.md"),
E0551: include_str!("./error_codes/E0551.md"),
@@ -467,7 +465,6 @@ E0777: include_str!("./error_codes/E0777.md"),
E0778: include_str!("./error_codes/E0778.md"),
E0779: include_str!("./error_codes/E0779.md"),
E0780: include_str!("./error_codes/E0780.md"),
-E0781: include_str!("./error_codes/E0781.md"),
;
// E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard
@@ -600,9 +597,11 @@ E0781: include_str!("./error_codes/E0781.md"),
E0514, // metadata version mismatch
E0519, // local crate and dependency have same (crate-name, disambiguator)
// two dependencies have same (crate-name, disambiguator) but different SVH
+ E0521, // borrowed data escapes outside of closure
E0523,
// E0526, // shuffle indices are not constant
// E0540, // multiple rustc_deprecated attributes
+ E0542, // missing 'since'
E0543, // missing 'reason'
E0544, // multiple stability levels
E0545, // incorrect 'issue'
diff --git a/compiler/rustc_error_codes/src/error_codes/E0074.md b/compiler/rustc_error_codes/src/error_codes/E0074.md
index 785d6de226d3d..e25dec7681be5 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0074.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0074.md
@@ -11,7 +11,7 @@ This will cause an error:
#![feature(repr_simd)]
#[repr(simd)]
-struct Bad(T, T, T, T);
+struct Bad(T, T, T);
```
This will not:
@@ -20,5 +20,5 @@ This will not:
#![feature(repr_simd)]
#[repr(simd)]
-struct Good(u32, u32, u32, u32);
+struct Good(u32, u32, u32);
```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0076.md b/compiler/rustc_error_codes/src/error_codes/E0076.md
index 1da8caa9506d7..f293a2a5772db 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0076.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0076.md
@@ -7,7 +7,7 @@ Erroneous code example:
#![feature(repr_simd)]
#[repr(simd)]
-struct Bad(u16, u32, u32 u32); // error!
+struct Bad(u16, u32, u32); // error!
```
When using the `#[simd]` attribute to automatically use SIMD operations in tuple
@@ -20,5 +20,5 @@ Fixed example:
#![feature(repr_simd)]
#[repr(simd)]
-struct Good(u32, u32, u32, u32); // ok!
+struct Good(u32, u32, u32); // ok!
```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0077.md b/compiler/rustc_error_codes/src/error_codes/E0077.md
index 91aa24d1f52f4..b14513c6ccf1f 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0077.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0077.md
@@ -19,5 +19,5 @@ Fixed example:
#![feature(repr_simd)]
#[repr(simd)]
-struct Good(u32, u32, u32, u32); // ok!
+struct Good(u32, u32, u32); // ok!
```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0463.md b/compiler/rustc_error_codes/src/error_codes/E0463.md
index d0cd1b1dcb75b..e46938c607d34 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0463.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0463.md
@@ -11,24 +11,3 @@ extern crate cake_is_a_lie; // error: can't find crate for `cake_is_a_lie`
You need to link your code to the relevant crate in order to be able to use it
(through Cargo or the `-L` option of rustc example). Plugins are crates as
well, and you link to them the same way.
-
-## Common causes
-
-- The crate is not present at all. If using Cargo, add it to `[dependencies]`
- in Cargo.toml.
-- The crate is present, but under a different name. If using Cargo, look for
- `package = ` under `[dependencies]` in Cargo.toml.
-
-## Common causes for missing `std` or `core`
-
-- You are cross-compiling for a target which doesn't have `std` prepackaged.
- Consider one of the following:
- + Adding a pre-compiled version of std with `rustup target add`
- + Building std from source with `cargo build -Z build-std`
- + Using `#![no_std]` at the crate root, so you won't need `std` in the first
- place.
-- You are developing the compiler itself and haven't built libstd from source.
- You can usually build it with `x.py build library/std`. More information
- about x.py is available in the [rustc-dev-guide].
-
-[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#building-the-compiler
diff --git a/compiler/rustc_error_codes/src/error_codes/E0521.md b/compiler/rustc_error_codes/src/error_codes/E0521.md
deleted file mode 100644
index 65dcac983acd5..0000000000000
--- a/compiler/rustc_error_codes/src/error_codes/E0521.md
+++ /dev/null
@@ -1,28 +0,0 @@
-Borrowed data escapes outside of closure.
-
-Erroneous code example:
-
-```compile_fail,E0521
-let mut list: Vec<&str> = Vec::new();
-
-let _add = |el: &str| {
- list.push(el); // error: `el` escapes the closure body here
-};
-```
-
-A type anotation of a closure parameter implies a new lifetime declaration.
-Consider to drop it, the compiler is reliably able to infer them.
-
-```
-let mut list: Vec<&str> = Vec::new();
-
-let _add = |el| {
- list.push(el);
-};
-```
-
-See the [Closure type inference and annotation][closure-infere-annotation] and
-[Lifetime elision][lifetime-elision] sections of the Book for more details.
-
-[closure-infere-annotation]: https://doc.rust-lang.org/book/ch13-01-closures.html#closure-type-inference-and-annotation
-[lifetime-elision]: https://doc.rust-lang.org/reference/lifetime-elision.html
diff --git a/compiler/rustc_error_codes/src/error_codes/E0542.md b/compiler/rustc_error_codes/src/error_codes/E0542.md
deleted file mode 100644
index dbbc34a71be2c..0000000000000
--- a/compiler/rustc_error_codes/src/error_codes/E0542.md
+++ /dev/null
@@ -1,47 +0,0 @@
-The `since` value is missing in a stability attribute.
-
-Erroneous code example:
-
-```compile_fail,E0542
-#![feature(staged_api)]
-#![stable(since = "1.0.0", feature = "test")]
-
-#[stable(feature = "_stable_fn")] // invalid
-fn _stable_fn() {}
-
-#[rustc_const_stable(feature = "_stable_const_fn")] // invalid
-fn _stable_const_fn() {}
-
-#[stable(feature = "_deprecated_fn", since = "0.1.0")]
-#[rustc_deprecated(
- reason = "explanation for deprecation"
-)] // invalid
-fn _deprecated_fn() {}
-```
-
-To fix the issue you need to provide the `since` field.
-
-```
-#![feature(staged_api)]
-#![stable(since = "1.0.0", feature = "test")]
-
-#[stable(feature = "_stable_fn", since = "1.0.0")] // ok!
-fn _stable_fn() {}
-
-#[rustc_const_stable(feature = "_stable_const_fn", since = "1.0.0")] // ok!
-fn _stable_const_fn() {}
-
-#[stable(feature = "_deprecated_fn", since = "0.1.0")]
-#[rustc_deprecated(
- since = "1.0.0",
- reason = "explanation for deprecation"
-)] // ok!
-fn _deprecated_fn() {}
-```
-
-See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix
-of the Book and the [Stability attributes][stability-attributes] section of the
-Rustc Dev Guide for more details.
-
-[how-rust-made-nightly]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
-[stability-attributes]: https://rustc-dev-guide.rust-lang.org/stability.html
diff --git a/compiler/rustc_error_codes/src/error_codes/E0546.md b/compiler/rustc_error_codes/src/error_codes/E0546.md
index 0073357b5ea84..b2df22c0f8fad 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0546.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0546.md
@@ -1,4 +1,4 @@
-The `feature` value is missing in a stability attribute.
+A feature name is missing.
Erroneous code example:
@@ -13,7 +13,7 @@ fn unstable_fn() {}
fn stable_fn() {}
```
-To fix the issue you need to provide the `feature` field.
+To fix the issue you need to provide a feature name.
```
#![feature(staged_api)]
@@ -25,10 +25,3 @@ fn unstable_fn() {}
#[stable(feature = "stable_fn", since = "1.0.0")] // ok!
fn stable_fn() {}
```
-
-See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix
-of the Book and the [Stability attributes][stability-attributes] section of the
-Rustc Dev Guide for more details.
-
-[how-rust-made-nightly]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
-[stability-attributes]: https://rustc-dev-guide.rust-lang.org/stability.html
diff --git a/compiler/rustc_error_codes/src/error_codes/E0781.md b/compiler/rustc_error_codes/src/error_codes/E0781.md
deleted file mode 100644
index 7641acfb5249e..0000000000000
--- a/compiler/rustc_error_codes/src/error_codes/E0781.md
+++ /dev/null
@@ -1,12 +0,0 @@
-The `C-cmse-nonsecure-call` ABI can only be used with function pointers.
-
-Erroneous code example:
-
-```compile_fail,E0781
-#![feature(abi_c_cmse_nonsecure_call)]
-
-pub extern "C-cmse-nonsecure-call" fn test() {}
-```
-
-The `C-cmse-nonsecure-call` ABI should be used by casting function pointers to
-specific addresses.
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index ef4a45cab4135..e61476bf23e1e 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -4,9 +4,7 @@ use crate::Level;
use crate::Substitution;
use crate::SubstitutionPart;
use crate::SuggestionStyle;
-use crate::ToolMetadata;
use rustc_lint_defs::Applicability;
-use rustc_serialize::json::Json;
use rustc_span::{MultiSpan, Span, DUMMY_SP};
use std::fmt;
@@ -305,7 +303,6 @@ impl Diagnostic {
msg: msg.to_owned(),
style: SuggestionStyle::ShowCode,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -331,7 +328,6 @@ impl Diagnostic {
msg: msg.to_owned(),
style: SuggestionStyle::ShowCode,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -358,7 +354,6 @@ impl Diagnostic {
msg: msg.to_owned(),
style: SuggestionStyle::CompletelyHidden,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -413,7 +408,6 @@ impl Diagnostic {
msg: msg.to_owned(),
style,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -452,7 +446,6 @@ impl Diagnostic {
msg: msg.to_owned(),
style: SuggestionStyle::ShowCode,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -522,23 +515,6 @@ impl Diagnostic {
self
}
- /// Adds a suggestion intended only for a tool. The intent is that the metadata encodes
- /// the suggestion in a tool-specific way, as it may not even directly involve Rust code.
- pub fn tool_only_suggestion_with_metadata(
- &mut self,
- msg: &str,
- applicability: Applicability,
- tool_metadata: Json,
- ) {
- self.suggestions.push(CodeSuggestion {
- substitutions: vec![],
- msg: msg.to_owned(),
- style: SuggestionStyle::CompletelyHidden,
- applicability,
- tool_metadata: ToolMetadata::new(tool_metadata),
- })
- }
-
pub fn set_span>(&mut self, sp: S) -> &mut Self {
self.span = sp.into();
if let Some(span) = self.span.primary_span() {
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index c09cce21bf24c..37902dddff46d 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -36,7 +36,7 @@ macro_rules! forward_inner_docs {
($e:expr => $i:item) => {
#[doc = $e]
$i
- };
+ }
}
/// In general, the `DiagnosticBuilder` uses deref to allow access to
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index ea62e21523028..00882bb287a4f 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -645,7 +645,7 @@ impl EmitterWriter {
margin: Margin,
) {
// Tabs are assumed to have been replaced by spaces in calling code.
- debug_assert!(!source_string.contains('\t'));
+ assert!(!source_string.contains('\t'));
let line_len = source_string.len();
// Create the source line we will highlight.
let left = margin.left(line_len);
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index c27b39a9d62ff..d57beb1148a25 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -14,7 +14,6 @@ use rustc_span::source_map::{FilePathMapping, SourceMap};
use crate::emitter::{Emitter, HumanReadableErrorType};
use crate::registry::Registry;
use crate::DiagnosticId;
-use crate::ToolMetadata;
use crate::{CodeSuggestion, SubDiagnostic};
use rustc_lint_defs::{Applicability, FutureBreakage};
@@ -27,7 +26,6 @@ use std::sync::{Arc, Mutex};
use std::vec;
use rustc_serialize::json::{as_json, as_pretty_json};
-use rustc_serialize::{Encodable, Encoder};
#[cfg(test)]
mod tests;
@@ -170,8 +168,7 @@ impl Emitter for JsonEmitter {
// The following data types are provided just for serialisation.
-// NOTE: this has a manual implementation of Encodable which needs to be updated in
-// parallel.
+#[derive(Encodable)]
struct Diagnostic {
/// The primary error message.
message: String,
@@ -183,65 +180,6 @@ struct Diagnostic {
children: Vec,
/// The message as rustc would render it.
rendered: Option,
- /// Extra tool metadata
- tool_metadata: ToolMetadata,
-}
-
-macro_rules! encode_fields {
- (
- $enc:expr, // encoder
- $idx:expr, // starting field index
- $struct:expr, // struct we're serializing
- $struct_name:ident, // struct name
- [ $($name:ident),+$(,)? ], // fields to encode
- [ $($ignore:ident),+$(,)? ] // fields we're skipping
- ) => {
- {
- // Pattern match to make sure all fields are accounted for
- let $struct_name { $($name,)+ $($ignore: _,)+ } = $struct;
- let mut idx = $idx;
- $(
- $enc.emit_struct_field(
- stringify!($name),
- idx,
- |enc| $name.encode(enc),
- )?;
- idx += 1;
- )+
- idx
- }
- };
-}
-
-// Special-case encoder to skip tool_metadata if not set
-impl Encodable for Diagnostic {
- fn encode(&self, s: &mut E) -> Result<(), E::Error> {
- s.emit_struct("diagnostic", 7, |s| {
- let mut idx = 0;
-
- idx = encode_fields!(
- s,
- idx,
- self,
- Self,
- [message, code, level, spans, children, rendered],
- [tool_metadata]
- );
- if self.tool_metadata.is_set() {
- idx = encode_fields!(
- s,
- idx,
- self,
- Self,
- [tool_metadata],
- [message, code, level, spans, children, rendered]
- );
- }
-
- let _ = idx;
- Ok(())
- })
- }
}
#[derive(Encodable)]
@@ -331,7 +269,6 @@ impl Diagnostic {
spans: DiagnosticSpan::from_suggestion(sugg, je),
children: vec![],
rendered: None,
- tool_metadata: sugg.tool_metadata.clone(),
});
// generate regular command line output and store it in the json
@@ -375,7 +312,6 @@ impl Diagnostic {
.chain(sugg)
.collect(),
rendered: Some(output),
- tool_metadata: ToolMetadata::default(),
}
}
@@ -391,7 +327,6 @@ impl Diagnostic {
.unwrap_or_else(|| DiagnosticSpan::from_multispan(&diag.span, je)),
children: vec![],
rendered: None,
- tool_metadata: ToolMetadata::default(),
}
}
}
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 9800ed9bfa948..e184e929b0745 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -23,13 +23,10 @@ use rustc_data_structures::sync::{self, Lock, Lrc};
use rustc_data_structures::AtomicRef;
use rustc_lint_defs::FutureBreakage;
pub use rustc_lint_defs::{pluralize, Applicability};
-use rustc_serialize::json::Json;
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::source_map::SourceMap;
use rustc_span::{Loc, MultiSpan, Span};
use std::borrow::Cow;
-use std::hash::{Hash, Hasher};
use std::panic;
use std::path::Path;
use std::{error, fmt};
@@ -76,39 +73,6 @@ impl SuggestionStyle {
}
}
-#[derive(Clone, Debug, PartialEq, Default)]
-pub struct ToolMetadata(pub Option);
-
-impl ToolMetadata {
- fn new(json: Json) -> Self {
- ToolMetadata(Some(json))
- }
-
- fn is_set(&self) -> bool {
- self.0.is_some()
- }
-}
-
-impl Hash for ToolMetadata {
- fn hash(&self, _state: &mut H) {}
-}
-
-// Doesn't really need to round-trip
-impl Decodable for ToolMetadata {
- fn decode(_d: &mut D) -> Result {
- Ok(ToolMetadata(None))
- }
-}
-
-impl Encodable for ToolMetadata {
- fn encode(&self, e: &mut S) -> Result<(), S::Error> {
- match &self.0 {
- None => e.emit_unit(),
- Some(json) => json.encode(e),
- }
- }
-}
-
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
pub struct CodeSuggestion {
/// Each substitute can have multiple variants due to multiple
@@ -142,8 +106,6 @@ pub struct CodeSuggestion {
/// which are useful for users but not useful for
/// tools like rustfix
pub applicability: Applicability,
- /// Tool-specific metadata
- pub tool_metadata: ToolMetadata,
}
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
@@ -813,6 +775,7 @@ impl HandlerInner {
}
let already_emitted = |this: &mut Self| {
+ use std::hash::Hash;
let mut hasher = StableHasher::new();
diagnostic.hash(&mut hasher);
let diagnostic_hash = hasher.finish();
@@ -938,7 +901,7 @@ impl HandlerInner {
fn span_bug(&mut self, sp: impl Into, msg: &str) -> ! {
self.emit_diag_at_span(Diagnostic::new(Bug, msg), sp);
- panic::panic_any(ExplicitBug);
+ panic!(ExplicitBug);
}
fn emit_diag_at_span(&mut self, mut diag: Diagnostic, sp: impl Into) {
@@ -992,7 +955,7 @@ impl HandlerInner {
fn bug(&mut self, msg: &str) -> ! {
self.emit_diagnostic(&Diagnostic::new(Bug, msg));
- panic::panic_any(ExplicitBug);
+ panic!(ExplicitBug);
}
fn delay_as_bug(&mut self, diagnostic: Diagnostic) {
diff --git a/compiler/rustc_errors/src/snippet.rs b/compiler/rustc_errors/src/snippet.rs
index acb88e57db5ee..dbb2523f28691 100644
--- a/compiler/rustc_errors/src/snippet.rs
+++ b/compiler/rustc_errors/src/snippet.rs
@@ -122,13 +122,11 @@ impl Annotation {
}
pub fn is_multiline(&self) -> bool {
- matches!(
- self.annotation_type,
+ matches!(self.annotation_type,
AnnotationType::Multiline(_)
- | AnnotationType::MultilineStart(_)
- | AnnotationType::MultilineLine(_)
- | AnnotationType::MultilineEnd(_)
- )
+ | AnnotationType::MultilineStart(_)
+ | AnnotationType::MultilineLine(_)
+ | AnnotationType::MultilineEnd(_))
}
pub fn len(&self) -> usize {
@@ -160,10 +158,7 @@ impl Annotation {
pub fn takes_space(&self) -> bool {
// Multiline annotations always have to keep vertical space.
- matches!(
- self.annotation_type,
- AnnotationType::MultilineStart(_) | AnnotationType::MultilineEnd(_)
- )
+ matches!(self.annotation_type, AnnotationType::MultilineStart(_) | AnnotationType::MultilineEnd(_))
}
}
diff --git a/compiler/rustc_errors/src/styled_buffer.rs b/compiler/rustc_errors/src/styled_buffer.rs
index ef71ee36ea36c..a4dd0f391bd3a 100644
--- a/compiler/rustc_errors/src/styled_buffer.rs
+++ b/compiler/rustc_errors/src/styled_buffer.rs
@@ -15,7 +15,7 @@ impl StyledBuffer {
pub fn render(&self) -> Vec> {
// Tabs are assumed to have been replaced by spaces in calling code.
- debug_assert!(self.text.iter().all(|r| !r.contains(&'\t')));
+ assert!(self.text.iter().all(|r| !r.contains(&'\t')));
let mut output: Vec> = vec![];
let mut styled_vec: Vec = vec![];
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 196a774355e10..08543d1622a7d 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -141,10 +141,7 @@ impl Annotatable {
}
crate fn into_tokens(self, sess: &ParseSess) -> TokenStream {
- // Tokens of an attribute target may be invalidated by some outer `#[derive]` performing
- // "full configuration" (attributes following derives on the same item should be the most
- // common case), that's why synthesizing tokens is allowed.
- nt_to_tokenstream(&self.into_nonterminal(), sess, CanSynthesizeMissingTokens::Yes)
+ nt_to_tokenstream(&self.into_nonterminal(), sess, CanSynthesizeMissingTokens::No)
}
pub fn expect_item(self) -> P {
@@ -237,6 +234,25 @@ impl Annotatable {
_ => panic!("expected variant"),
}
}
+
+ pub fn derive_allowed(&self) -> bool {
+ match *self {
+ Annotatable::Stmt(ref stmt) => match stmt.kind {
+ ast::StmtKind::Item(ref item) => matches!(
+ item.kind,
+ ast::ItemKind::Struct(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Union(..)
+ ),
+ _ => false,
+ },
+ Annotatable::Item(ref item) => match item.kind {
+ ast::ItemKind::Struct(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Union(..) => {
+ true
+ }
+ _ => false,
+ },
+ _ => false,
+ }
+ }
}
/// Result of an expansion that may need to be retried.
@@ -838,6 +854,12 @@ impl SyntaxExtension {
}
}
+/// Result of resolving a macro invocation.
+pub enum InvocationRes {
+ Single(Lrc),
+ DeriveContainer(Vec>),
+}
+
/// Error type that denotes indeterminacy.
pub struct Indeterminate;
@@ -863,29 +885,16 @@ pub trait ResolverExpand {
invoc: &Invocation,
eager_expansion_root: ExpnId,
force: bool,
- ) -> Result, Indeterminate>;
+ ) -> Result;
fn check_unused_macros(&mut self);
/// Some parent node that is close enough to the given macro call.
- fn lint_node_id(&self, expn_id: ExpnId) -> NodeId;
+ fn lint_node_id(&mut self, expn_id: ExpnId) -> NodeId;
// Resolver interfaces for specific built-in macros.
/// Does `#[derive(...)]` attribute with the given `ExpnId` have built-in `Copy` inside it?
fn has_derive_copy(&self, expn_id: ExpnId) -> bool;
- /// Resolve paths inside the `#[derive(...)]` attribute with the given `ExpnId`.
- fn resolve_derives(
- &mut self,
- expn_id: ExpnId,
- derives: Vec,
- force: bool,
- ) -> Result<(), Indeterminate>;
- /// Take resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId`
- /// back from resolver.
- fn take_derive_resolutions(
- &mut self,
- expn_id: ExpnId,
- ) -> Option, ast::Path)>>;
/// Path resolution logic for `#[cfg_accessible(path)]`.
fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result;
}
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 870b5c92d8983..50832d5edbfc5 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1,26 +1,24 @@
use crate::base::*;
use crate::config::StripUnconfigured;
use crate::configure;
-use crate::hygiene::SyntaxContext;
+use crate::hygiene::{ExpnData, ExpnKind, SyntaxContext};
use crate::mbe::macro_rules::annotate_err_with_kind;
use crate::module::{parse_external_mod, push_directory, Directory, DirectoryOwnership};
use crate::placeholders::{placeholder, PlaceholderExpander};
+use crate::proc_macro::collect_derives;
-use rustc_ast as ast;
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{self, AssocCtxt, Visitor};
-use rustc_ast::{AttrItem, AttrStyle, Block, ItemKind, LitKind, MacArgs};
-use rustc_ast::{MacCallStmt, MacStmtStyle, MetaItemKind, NestedMetaItem};
-use rustc_ast::{NodeId, PatKind, Path, StmtKind, Unsafe};
+use rustc_ast::{self as ast, AttrItem, AttrStyle, Block, LitKind, NodeId, PatKind, Path};
+use rustc_ast::{ItemKind, MacArgs, MacCallStmt, MacStmtStyle, StmtKind, Unsafe};
use rustc_ast_pretty::pprust;
use rustc_attr::{self as attr, is_builtin_attr, HasAttrs};
use rustc_data_structures::map_in_place::MapInPlace;
use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_data_structures::sync::Lrc;
-use rustc_errors::{Applicability, PResult};
+use rustc_errors::{struct_span_err, Applicability, PResult};
use rustc_feature::Features;
use rustc_parse::parser::{AttemptLocalParseRecovery, ForceCollect, Parser};
use rustc_parse::validate_attr;
@@ -304,11 +302,20 @@ pub enum InvocationKind {
item: Annotatable,
// Required for resolving derive helper attributes.
derives: Vec,
+ // We temporarily report errors for attribute macros placed after derives
+ after_derive: bool,
},
Derive {
path: Path,
item: Annotatable,
},
+ /// "Invocation" that contains all derives from an item,
+ /// broken into multiple `Derive` invocations when expanded.
+ /// FIXME: Find a way to remove it.
+ DeriveContainer {
+ derives: Vec,
+ item: Annotatable,
+ },
}
impl InvocationKind {
@@ -321,6 +328,7 @@ impl InvocationKind {
match self {
InvocationKind::Attr { item: Annotatable::StructField(field), .. }
| InvocationKind::Derive { item: Annotatable::StructField(field), .. }
+ | InvocationKind::DeriveContainer { item: Annotatable::StructField(field), .. }
if field.ident.is_none() =>
{
Some(field.vis.clone())
@@ -336,6 +344,7 @@ impl Invocation {
InvocationKind::Bang { span, .. } => *span,
InvocationKind::Attr { attr, .. } => attr.span,
InvocationKind::Derive { path, .. } => path.span,
+ InvocationKind::DeriveContainer { item, .. } => item.span(),
}
}
}
@@ -437,7 +446,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
let mut undetermined_invocations = Vec::new();
let (mut progress, mut force) = (false, !self.monotonic);
loop {
- let (invoc, ext) = if let Some(invoc) = invocations.pop() {
+ let (invoc, res) = if let Some(invoc) = invocations.pop() {
invoc
} else {
self.resolve_imports();
@@ -455,8 +464,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
continue;
};
- let ext = match ext {
- Some(ext) => ext,
+ let res = match res {
+ Some(res) => res,
None => {
let eager_expansion_root = if self.monotonic {
invoc.expansion_data.id
@@ -468,7 +477,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
eager_expansion_root,
force,
) {
- Ok(ext) => ext,
+ Ok(res) => res,
Err(Indeterminate) => {
// Cannot resolve, will retry this invocation later.
undetermined_invocations.push((invoc, None));
@@ -482,78 +491,86 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
self.cx.current_expansion = invoc.expansion_data.clone();
self.cx.force_mode = force;
+ // FIXME(jseyfried): Refactor out the following logic
let fragment_kind = invoc.fragment_kind;
- let (expanded_fragment, new_invocations) = match self.expand_invoc(invoc, &ext.kind) {
- ExpandResult::Ready(fragment) => {
- let derive_placeholders = self
- .cx
- .resolver
- .take_derive_resolutions(expn_id)
- .map(|derives| {
- enum AnnotatableRef<'a> {
- Item(&'a P),
- Stmt(&'a ast::Stmt),
+ let (expanded_fragment, new_invocations) = match res {
+ InvocationRes::Single(ext) => match self.expand_invoc(invoc, &ext.kind) {
+ ExpandResult::Ready(fragment) => self.collect_invocations(fragment, &[]),
+ ExpandResult::Retry(invoc) => {
+ if force {
+ self.cx.span_bug(
+ invoc.span(),
+ "expansion entered force mode but is still stuck",
+ );
+ } else {
+ // Cannot expand, will retry this invocation later.
+ undetermined_invocations
+ .push((invoc, Some(InvocationRes::Single(ext))));
+ continue;
+ }
+ }
+ },
+ InvocationRes::DeriveContainer(_exts) => {
+ // FIXME: Consider using the derive resolutions (`_exts`) immediately,
+ // instead of enqueuing the derives to be resolved again later.
+ let (derives, mut item) = match invoc.kind {
+ InvocationKind::DeriveContainer { derives, item } => (derives, item),
+ _ => unreachable!(),
+ };
+ let (item, derive_placeholders) = if !item.derive_allowed() {
+ self.error_derive_forbidden_on_non_adt(&derives, &item);
+ item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
+ (item, Vec::new())
+ } else {
+ let mut visitor = StripUnconfigured {
+ sess: self.cx.sess,
+ features: self.cx.ecfg.features,
+ modified: false,
+ };
+ let mut item = visitor.fully_configure(item);
+ item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
+ if visitor.modified && !derives.is_empty() {
+ // Erase the tokens if cfg-stripping modified the item
+ // This will cause us to synthesize fake tokens
+ // when `nt_to_tokenstream` is called on this item.
+ match &mut item {
+ Annotatable::Item(item) => item.tokens = None,
+ Annotatable::Stmt(stmt) => {
+ if let StmtKind::Item(item) = &mut stmt.kind {
+ item.tokens = None
+ } else {
+ panic!("Unexpected stmt {:?}", stmt);
+ }
+ }
+ _ => panic!("Unexpected annotatable {:?}", item),
}
- let item = match &fragment {
- AstFragment::Items(items) => match &items[..] {
- [item] => AnnotatableRef::Item(item),
- _ => unreachable!(),
- },
- AstFragment::Stmts(stmts) => match &stmts[..] {
- [stmt] => AnnotatableRef::Stmt(stmt),
- _ => unreachable!(),
- },
- _ => unreachable!(),
- };
+ }
- invocations.reserve(derives.len());
- derives
- .into_iter()
- .map(|(_exts, path)| {
- // FIXME: Consider using the derive resolutions (`_exts`)
- // instead of enqueuing the derives to be resolved again later.
- let expn_id = ExpnId::fresh(None);
- invocations.push((
- Invocation {
- kind: InvocationKind::Derive {
- path,
- item: match item {
- AnnotatableRef::Item(item) => {
- Annotatable::Item(item.clone())
- }
- AnnotatableRef::Stmt(stmt) => {
- Annotatable::Stmt(P(stmt.clone()))
- }
- },
- },
- fragment_kind,
- expansion_data: ExpansionData {
- id: expn_id,
- ..self.cx.current_expansion.clone()
- },
+ invocations.reserve(derives.len());
+ let derive_placeholders = derives
+ .into_iter()
+ .map(|path| {
+ let expn_id = ExpnId::fresh(None);
+ invocations.push((
+ Invocation {
+ kind: InvocationKind::Derive { path, item: item.clone() },
+ fragment_kind,
+ expansion_data: ExpansionData {
+ id: expn_id,
+ ..self.cx.current_expansion.clone()
},
- None,
- ));
- NodeId::placeholder_from_expn_id(expn_id)
- })
- .collect::>()
- })
- .unwrap_or_default();
+ },
+ None,
+ ));
+ NodeId::placeholder_from_expn_id(expn_id)
+ })
+ .collect::>();
+ (item, derive_placeholders)
+ };
+ let fragment = fragment_kind.expect_from_annotatables(::std::iter::once(item));
self.collect_invocations(fragment, &derive_placeholders)
}
- ExpandResult::Retry(invoc) => {
- if force {
- self.cx.span_bug(
- invoc.span(),
- "expansion entered force mode but is still stuck",
- );
- } else {
- // Cannot expand, will retry this invocation later.
- undetermined_invocations.push((invoc, Some(ext)));
- continue;
- }
- }
};
progress = true;
@@ -579,6 +596,29 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
fragment_with_placeholders
}
+ fn error_derive_forbidden_on_non_adt(&self, derives: &[Path], item: &Annotatable) {
+ let attr = self.cx.sess.find_by_name(item.attrs(), sym::derive);
+ let span = attr.map_or(item.span(), |attr| attr.span);
+ let mut err = struct_span_err!(
+ self.cx.sess,
+ span,
+ E0774,
+ "`derive` may only be applied to structs, enums and unions",
+ );
+ if let Some(ast::Attribute { style: ast::AttrStyle::Inner, .. }) = attr {
+ let trait_list = derives.iter().map(|t| pprust::path_to_string(t)).collect::>();
+ let suggestion = format!("#[derive({})]", trait_list.join(", "));
+ err.span_suggestion(
+ span,
+ "try an outer attribute",
+ suggestion,
+ // We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT
+ Applicability::MaybeIncorrect,
+ );
+ }
+ err.emit();
+ }
+
fn resolve_imports(&mut self) {
if self.monotonic {
self.cx.resolver.resolve_imports();
@@ -593,7 +633,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
&mut self,
mut fragment: AstFragment,
extra_placeholders: &[NodeId],
- ) -> (AstFragment, Vec<(Invocation, Option>)>) {
+ ) -> (AstFragment, Vec<(Invocation, Option)>) {
// Resolve `$crate`s in the fragment for pretty-printing.
self.cx.resolver.resolve_dollar_crates();
@@ -693,7 +733,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
_ => unreachable!(),
},
- InvocationKind::Attr { attr, mut item, derives } => match ext {
+ InvocationKind::Attr { attr, mut item, derives, after_derive } => match ext {
SyntaxExtensionKind::Attr(expander) => {
self.gate_proc_macro_input(&item);
self.gate_proc_macro_attr_item(span, &item);
@@ -724,7 +764,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
ExpandResult::Retry(item) => {
// Reassemble the original invocation for retrying.
return ExpandResult::Retry(Invocation {
- kind: InvocationKind::Attr { attr, item, derives },
+ kind: InvocationKind::Attr {
+ attr,
+ item,
+ derives,
+ after_derive,
+ },
..invoc
});
}
@@ -768,6 +813,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
_ => unreachable!(),
},
+ InvocationKind::DeriveContainer { .. } => unreachable!(),
})
}
@@ -850,9 +896,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
fragment
}
Err(mut err) => {
- if err.span.is_dummy() {
- err.set_span(span);
- }
+ err.set_span(span);
annotate_err_with_kind(&mut err, kind, span);
err.emit();
self.cx.trace_macros_diag();
@@ -965,13 +1009,29 @@ pub fn ensure_complete_parse<'a>(
struct InvocationCollector<'a, 'b> {
cx: &'a mut ExtCtxt<'b>,
cfg: StripUnconfigured<'a>,
- invocations: Vec<(Invocation, Option>)>,
+ invocations: Vec<(Invocation, Option)>,
monotonic: bool,
}
impl<'a, 'b> InvocationCollector<'a, 'b> {
fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment {
- let expn_id = ExpnId::fresh(None);
+ // Expansion data for all the collected invocations is set upon their resolution,
+ // with exception of the derive container case which is not resolved and can get
+ // its expansion data immediately.
+ let expn_data = match &kind {
+ InvocationKind::DeriveContainer { item, .. } => {
+ let mut expn_data = ExpnData::default(
+ ExpnKind::Macro(MacroKind::Attr, sym::derive),
+ item.span(),
+ self.cx.sess.parse_sess.edition,
+ None,
+ );
+ expn_data.parent = self.cx.current_expansion.id;
+ Some(expn_data)
+ }
+ _ => None,
+ };
+ let expn_id = ExpnId::fresh(expn_data);
let vis = kind.placeholder_visibility();
self.invocations.push((
Invocation {
@@ -999,44 +1059,64 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
fn collect_attr(
&mut self,
- (attr, derives): (ast::Attribute, Vec),
+ (attr, derives, after_derive): (Option, Vec, bool),
item: Annotatable,
kind: AstFragmentKind,
) -> AstFragment {
- self.collect(kind, InvocationKind::Attr { attr, item, derives })
+ self.collect(
+ kind,
+ match attr {
+ Some(attr) => InvocationKind::Attr { attr, item, derives, after_derive },
+ None => InvocationKind::DeriveContainer { derives, item },
+ },
+ )
}
- /// If `item` is an attribute invocation, remove the attribute and return it together with
- /// derives following it. We have to collect the derives in order to resolve legacy derive
- /// helpers (helpers written before derives that introduce them).
- fn take_first_attr(&mut self, item: &mut impl HasAttrs) -> Option<(ast::Attribute, Vec)> {
- let mut attr = None;
-
- item.visit_attrs(|attrs| {
- attr = attrs
- .iter()
- .position(|a| !self.cx.sess.is_attr_known(a) && !is_builtin_attr(a))
- .map(|attr_pos| {
- let attr = attrs.remove(attr_pos);
- let following_derives = attrs[attr_pos..]
- .iter()
- .filter(|a| a.has_name(sym::derive))
- .flat_map(|a| a.meta_item_list().unwrap_or_default())
- .filter_map(|nested_meta| match nested_meta {
- NestedMetaItem::MetaItem(ast::MetaItem {
- kind: MetaItemKind::Word,
- path,
- ..
- }) => Some(path),
- _ => None,
- })
- .collect();
-
- (attr, following_derives)
- })
+ fn find_attr_invoc(
+ &self,
+ attrs: &mut Vec,
+ after_derive: &mut bool,
+ ) -> Option {
+ attrs
+ .iter()
+ .position(|a| {
+ if a.has_name(sym::derive) {
+ *after_derive = true;
+ }
+ !self.cx.sess.is_attr_known(a) && !is_builtin_attr(a)
+ })
+ .map(|i| attrs.remove(i))
+ }
+
+ /// If `item` is an attr invocation, remove and return the macro attribute and derive traits.
+ fn take_first_attr(
+ &mut self,
+ item: &mut impl HasAttrs,
+ ) -> Option<(Option, Vec, /* after_derive */ bool)> {
+ let (mut attr, mut traits, mut after_derive) = (None, Vec::new(), false);
+
+ item.visit_attrs(|mut attrs| {
+ attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
+ traits = collect_derives(&mut self.cx, &mut attrs);
+ });
+
+ if attr.is_some() || !traits.is_empty() { Some((attr, traits, after_derive)) } else { None }
+ }
+
+ /// Alternative to `take_first_attr()` that ignores `#[derive]` so invocations fallthrough
+ /// to the unused-attributes lint (making it an error on statements and expressions
+ /// is a breaking change)
+ fn take_first_attr_no_derive(
+ &mut self,
+ nonitem: &mut impl HasAttrs,
+ ) -> Option<(Option, Vec, /* after_derive */ bool)> {
+ let (mut attr, mut after_derive) = (None, false);
+
+ nonitem.visit_attrs(|mut attrs| {
+ attr = self.find_attr_invoc(&mut attrs, &mut after_derive);
});
- attr
+ attr.map(|attr| (Some(attr), Vec::new(), after_derive))
}
fn configure(&mut self, node: T) -> Option {
@@ -1050,6 +1130,17 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
for attr in attrs.iter() {
rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features);
validate_attr::check_meta(&self.cx.sess.parse_sess, attr);
+
+ // macros are expanded before any lint passes so this warning has to be hardcoded
+ if attr.has_name(sym::derive) {
+ self.cx
+ .parse_sess()
+ .span_diagnostic
+ .struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
+ .note("this may become a hard error in a future release")
+ .emit();
+ }
+
if attr.doc_str().is_some() {
self.cx.sess.parse_sess.buffer_lint_with_diagnostic(
&UNUSED_DOC_COMMENTS,
@@ -1069,10 +1160,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
visit_clobber(expr.deref_mut(), |mut expr| {
self.cfg.configure_expr_kind(&mut expr.kind);
- if let Some(attr) = self.take_first_attr(&mut expr) {
+ if let Some(attr) = self.take_first_attr_no_derive(&mut expr) {
// Collect the invoc regardless of whether or not attributes are permitted here
// expansion will eat the attribute so it won't error later.
- self.cfg.maybe_emit_expr_attr_err(&attr.0);
+ if let Some(attr) = attr.0.as_ref() {
+ self.cfg.maybe_emit_expr_attr_err(attr)
+ }
// AstFragmentKind::Expr requires the macro to emit an expression.
return self
@@ -1168,8 +1261,10 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
expr.filter_map(|mut expr| {
self.cfg.configure_expr_kind(&mut expr.kind);
- if let Some(attr) = self.take_first_attr(&mut expr) {
- self.cfg.maybe_emit_expr_attr_err(&attr.0);
+ if let Some(attr) = self.take_first_attr_no_derive(&mut expr) {
+ if let Some(attr) = attr.0.as_ref() {
+ self.cfg.maybe_emit_expr_attr_err(attr)
+ }
return self
.collect_attr(attr, Annotatable::Expr(P(expr)), AstFragmentKind::OptExpr)
@@ -1211,7 +1306,15 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
// we'll expand attributes on expressions separately
if !stmt.is_expr() {
- if let Some(attr) = self.take_first_attr(&mut stmt) {
+ let attr = if stmt.is_item() {
+ self.take_first_attr(&mut stmt)
+ } else {
+ // Ignore derives on non-item statements for backwards compatibility.
+ // This will result in a unused attribute warning
+ self.take_first_attr_no_derive(&mut stmt)
+ };
+
+ if let Some(attr) = attr {
return self
.collect_attr(attr, Annotatable::Stmt(P(stmt)), AstFragmentKind::Stmts)
.make_stmts();
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index 8cbaa7c945a81..6779734cfc176 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -1,14 +1,16 @@
use crate::base::{self, *};
use crate::proc_macro_server;
-use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree};
+use rustc_ast::{self as ast, *};
use rustc_data_structures::sync::Lrc;
-use rustc_errors::ErrorReported;
+use rustc_errors::{struct_span_err, Applicability, ErrorReported};
+use rustc_lexer::is_ident;
use rustc_parse::nt_to_tokenstream;
use rustc_parse::parser::ForceCollect;
+use rustc_span::symbol::sym;
use rustc_span::{Span, DUMMY_SP};
const EXEC_STRATEGY: pm::bridge::server::SameThread = pm::bridge::server::SameThread;
@@ -140,3 +142,91 @@ impl MultiItemModifier for ProcMacroDerive {
ExpandResult::Ready(items)
}
}
+
+crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec) -> Vec {
+ let mut result = Vec::new();
+ attrs.retain(|attr| {
+ if !attr.has_name(sym::derive) {
+ return true;
+ }
+
+ // 1) First let's ensure that it's a meta item.
+ let nmis = match attr.meta_item_list() {
+ None => {
+ cx.struct_span_err(attr.span, "malformed `derive` attribute input")
+ .span_suggestion(
+ attr.span,
+ "missing traits to be derived",
+ "#[derive(Trait1, Trait2, ...)]".to_owned(),
+ Applicability::HasPlaceholders,
+ )
+ .emit();
+ return false;
+ }
+ Some(x) => x,
+ };
+
+ let mut error_reported_filter_map = false;
+ let mut error_reported_map = false;
+ let traits = nmis
+ .into_iter()
+ // 2) Moreover, let's ensure we have a path and not `#[derive("foo")]`.
+ .filter_map(|nmi| match nmi {
+ NestedMetaItem::Literal(lit) => {
+ error_reported_filter_map = true;
+ let mut err = struct_span_err!(
+ cx.sess,
+ lit.span,
+ E0777,
+ "expected path to a trait, found literal",
+ );
+ let token = lit.token.to_string();
+ if token.starts_with('"')
+ && token.len() > 2
+ && is_ident(&token[1..token.len() - 1])
+ {
+ err.help(&format!("try using `#[derive({})]`", &token[1..token.len() - 1]));
+ } else {
+ err.help("for example, write `#[derive(Debug)]` for `Debug`");
+ }
+ err.emit();
+ None
+ }
+ NestedMetaItem::MetaItem(mi) => Some(mi),
+ })
+ // 3) Finally, we only accept `#[derive($path_0, $path_1, ..)]`
+ // but not e.g. `#[derive($path_0 = "value", $path_1(abc))]`.
+ // In this case we can still at least determine that the user
+ // wanted this trait to be derived, so let's keep it.
+ .map(|mi| {
+ let mut traits_dont_accept = |title, action| {
+ error_reported_map = true;
+ let sp = mi.span.with_lo(mi.path.span.hi());
+ cx.struct_span_err(sp, title)
+ .span_suggestion(
+ sp,
+ action,
+ String::new(),
+ Applicability::MachineApplicable,
+ )
+ .emit();
+ };
+ match &mi.kind {
+ MetaItemKind::List(..) => traits_dont_accept(
+ "traits in `#[derive(...)]` don't accept arguments",
+ "remove the arguments",
+ ),
+ MetaItemKind::NameValue(..) => traits_dont_accept(
+ "traits in `#[derive(...)]` don't accept values",
+ "remove the value",
+ ),
+ MetaItemKind::Word => {}
+ }
+ mi.path
+ });
+
+ result.extend(traits);
+ !error_reported_filter_map && !error_reported_map
+ });
+ result
+}
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 2d0009c225c59..e12b533b110d2 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -628,16 +628,6 @@ declare_features! (
/// Allows using `pointer` and `reference` in intra-doc links
(active, intra_doc_pointers, "1.51.0", Some(80896), None),
-
- /// Allows `extern "C-cmse-nonsecure-call" fn()`.
- (active, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391), None),
-
- /// Lessens the requirements for structs to implement `Unsize`.
- (active, relaxed_struct_unsize, "1.51.0", Some(1), None),
-
- /// Allows macro attributes to observe output of `#[derive]`.
- (active, macro_attributes_in_derive_output, "1.51.0", Some(81119), None),
-
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index ac50703b5444e..3ed5320da73b3 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -188,6 +188,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
ungated!(reexport_test_harness_main, Normal, template!(NameValueStr: "name")),
// Macros:
+ ungated!(derive, Normal, template!(List: "Trait1, Trait2, ...")),
ungated!(automatically_derived, Normal, template!(Word)),
// FIXME(#14407)
ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ...")),
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 49d9e3b60b492..35170fa7c1d02 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -358,7 +358,7 @@ impl GenericArgs<'_> {
.iter()
.filter(|arg| !arg.is_synthetic())
.map(|arg| arg.span())
- .reduce(|span1, span2| span1.to(span2))
+ .fold_first(|span1, span2| span1.to(span2))
}
/// Returns span encompassing arguments and their surrounding `<>` or `()`
@@ -1543,10 +1543,10 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
**qpath,
QPath::LangItem(
LangItem::Range
- | LangItem::RangeTo
- | LangItem::RangeFrom
- | LangItem::RangeFull
- | LangItem::RangeToInclusive,
+ | LangItem::RangeTo
+ | LangItem::RangeFrom
+ | LangItem::RangeFull
+ | LangItem::RangeToInclusive,
_,
)
),
@@ -2015,7 +2015,6 @@ pub struct TypeBinding<'hir> {
pub hir_id: HirId,
#[stable_hasher(project(name))]
pub ident: Ident,
- pub gen_args: &'hir GenericArgs<'hir>,
pub kind: TypeBindingKind<'hir>,
pub span: Span,
}
@@ -2058,28 +2057,6 @@ pub enum PrimTy {
}
impl PrimTy {
- /// All of the primitive types
- pub const ALL: [Self; 17] = [
- // any changes here should also be reflected in `PrimTy::from_name`
- Self::Int(IntTy::I8),
- Self::Int(IntTy::I16),
- Self::Int(IntTy::I32),
- Self::Int(IntTy::I64),
- Self::Int(IntTy::I128),
- Self::Int(IntTy::Isize),
- Self::Uint(UintTy::U8),
- Self::Uint(UintTy::U16),
- Self::Uint(UintTy::U32),
- Self::Uint(UintTy::U64),
- Self::Uint(UintTy::U128),
- Self::Uint(UintTy::Usize),
- Self::Float(FloatTy::F32),
- Self::Float(FloatTy::F64),
- Self::Bool,
- Self::Char,
- Self::Str,
- ];
-
pub fn name_str(self) -> &'static str {
match self {
PrimTy::Int(i) => i.name_str(),
@@ -2101,33 +2078,6 @@ impl PrimTy {
PrimTy::Char => sym::char,
}
}
-
- /// Returns the matching `PrimTy` for a `Symbol` such as "str" or "i32".
- /// Returns `None` if no matching type is found.
- pub fn from_name(name: Symbol) -> Option {
- let ty = match name {
- // any changes here should also be reflected in `PrimTy::ALL`
- sym::i8 => Self::Int(IntTy::I8),
- sym::i16 => Self::Int(IntTy::I16),
- sym::i32 => Self::Int(IntTy::I32),
- sym::i64 => Self::Int(IntTy::I64),
- sym::i128 => Self::Int(IntTy::I128),
- sym::isize => Self::Int(IntTy::Isize),
- sym::u8 => Self::Uint(UintTy::U8),
- sym::u16 => Self::Uint(UintTy::U16),
- sym::u32 => Self::Uint(UintTy::U32),
- sym::u64 => Self::Uint(UintTy::U64),
- sym::u128 => Self::Uint(UintTy::U128),
- sym::usize => Self::Uint(UintTy::Usize),
- sym::f32 => Self::Float(FloatTy::F32),
- sym::f64 => Self::Float(FloatTy::F64),
- sym::bool => Self::Bool,
- sym::char => Self::Char,
- sym::str => Self::Str,
- _ => return None,
- };
- Some(ty)
- }
}
#[derive(Debug, HashStable_Generic)]
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index f8b3f0d9b6e23..6c1bee2335a00 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -781,7 +781,6 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(
) {
visitor.visit_id(type_binding.hir_id);
visitor.visit_ident(type_binding.ident);
- visitor.visit_generic_args(type_binding.span, type_binding.gen_args);
match type_binding.kind {
TypeBindingKind::Equality { ref ty } => {
visitor.visit_ty(ty);
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index c69a9b063aeca..efc516a662fb7 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -6,6 +6,7 @@
#![feature(const_fn)] // For the unsizing cast on `&[]`
#![feature(const_panic)]
#![feature(in_band_lifetimes)]
+#![feature(iterator_fold_self)]
#![feature(once_cell)]
#![feature(or_patterns)]
#![recursion_limit = "256"]
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 4595855309fda..f1c2a6b7e6e85 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1840,7 +1840,6 @@ impl<'a> State<'a> {
for binding in generic_args.bindings.iter() {
start_or_comma(self);
self.print_ident(binding.ident);
- self.print_generic_args(binding.gen_args, false, false);
self.s.space();
match generic_args.bindings[0].kind {
hir::TypeBindingKind::Equality { ref ty } => {
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs
index 100824f4b9448..0b501da7cd975 100644
--- a/compiler/rustc_index/src/bit_set.rs
+++ b/compiler/rustc_index/src/bit_set.rs
@@ -707,18 +707,6 @@ impl GrowableBitSet {
self.bit_set.insert(elem)
}
- /// Returns `true` if the set has changed.
- #[inline]
- pub fn remove(&mut self, elem: T) -> bool {
- self.ensure(elem.index() + 1);
- self.bit_set.remove(elem)
- }
-
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.bit_set.is_empty()
- }
-
#[inline]
pub fn contains(&self, elem: T) -> bool {
let (word_index, mask) = word_index_and_mask(elem);
diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs
index c11b98e77aa58..6cc3e9427d1a7 100644
--- a/compiler/rustc_index/src/bit_set/tests.rs
+++ b/compiler/rustc_index/src/bit_set/tests.rs
@@ -1,7 +1,6 @@
use super::*;
extern crate test;
-use std::hint::black_box;
use test::Bencher;
#[test]
@@ -365,36 +364,3 @@ fn union_hybrid_sparse_full_small_domain(b: &mut Bencher) {
sparse.union(&dense);
})
}
-
-#[bench]
-fn bench_insert(b: &mut Bencher) {
- let mut bs = BitSet::new_filled(99999usize);
- b.iter(|| {
- black_box(bs.insert(black_box(100u32)));
- });
-}
-
-#[bench]
-fn bench_remove(b: &mut Bencher) {
- let mut bs = BitSet::new_filled(99999usize);
- b.iter(|| {
- black_box(bs.remove(black_box(100u32)));
- });
-}
-
-#[bench]
-fn bench_iter(b: &mut Bencher) {
- let bs = BitSet::new_filled(99999usize);
- b.iter(|| {
- bs.iter().map(|b: usize| black_box(b)).for_each(drop);
- });
-}
-
-#[bench]
-fn bench_intersect(b: &mut Bencher) {
- let mut ba: BitSet = BitSet::new_filled(99999usize);
- let bb = BitSet::new_filled(99999usize);
- b.iter(|| {
- ba.intersect(black_box(&bb));
- });
-}
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index 995034e81da28..eaef4c7b54a62 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -8,7 +8,3 @@
pub mod bit_set;
pub mod vec;
-
-// FIXME(#56935): Work around ICEs during cross-compilation.
-#[allow(unused)]
-extern crate rustc_macros;
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index aa4fd055d5ee0..9002d251f1237 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -353,8 +353,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
// `TyVar(vid)` is unresolved, track its universe index in the canonicalized
// result.
Err(mut ui) => {
- // FIXME: perf problem described in #55921.
- ui = ty::UniverseIndex::ROOT;
+ if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
+ // FIXME: perf problem described in #55921.
+ ui = ty::UniverseIndex::ROOT;
+ }
self.canonicalize_ty_var(
CanonicalVarInfo {
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
@@ -438,8 +440,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
// `ConstVar(vid)` is unresolved, track its universe index in the
// canonicalized result
Err(mut ui) => {
- // FIXME: perf problem described in #55921.
- ui = ty::UniverseIndex::ROOT;
+ if !self.infcx.unwrap().tcx.sess.opts.debugging_opts.chalk {
+ // FIXME: perf problem described in #55921.
+ ui = ty::UniverseIndex::ROOT;
+ }
return self.canonicalize_const_var(
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
ct,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 84aa19aedebf8..2abb1c725b914 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1855,7 +1855,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
diag.span_suggestion(
span,
&format!(
- "you might have meant to use field `{}` whose type is `{}`",
+ "you might have meant to use field `{}` of type `{}`",
name, ty
),
suggestion,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index 61c8113d05287..0958afa03082a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -132,12 +132,7 @@ impl Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
[segment]
if segment
.res
- .map(|res| {
- matches!(
- res,
- Res::SelfTy(_, _) | Res::Def(hir::def::DefKind::TyParam, _)
- )
- })
+ .map(|res| matches!(res, Res::SelfTy(_, _) | Res::Def(hir::def::DefKind::TyParam, _)))
.unwrap_or(false) =>
{
self.types.push(path.span);
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md b/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md
index 0a7da8c80639c..e0b2c0bffeeb3 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/README.md
@@ -1,3 +1,4 @@
+
Lexical Region Resolution was removed in https://github.com/rust-lang/rust/pull/64790.
Rust now uses Non-lexical lifetimes. For more info, please see the [borrowck
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 87684c2715f4e..13cf1e1083f7f 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -1,10 +1,9 @@
use smallvec::smallvec;
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
-use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
+use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::outlives::Component;
use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
-use rustc_span::symbol::Ident;
pub fn anonymize_predicate<'tcx>(
tcx: TyCtxt<'tcx>,
@@ -283,44 +282,6 @@ pub fn transitive_bounds<'tcx>(
elaborate_trait_refs(tcx, bounds).filter_to_traits()
}
-/// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may
-/// define the given associated type `assoc_name`. It uses the
-/// `super_predicates_that_define_assoc_type` query to avoid enumerating super-predicates that
-/// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or
-/// `T::Item` and helps to avoid cycle errors (see e.g. #35237).
-pub fn transitive_bounds_that_define_assoc_type<'tcx>(
- tcx: TyCtxt<'tcx>,
- bounds: impl Iterator- >,
- assoc_name: Ident,
-) -> impl Iterator
- > {
- let mut stack: Vec<_> = bounds.collect();
- let mut visited = FxIndexSet::default();
-
- std::iter::from_fn(move || {
- while let Some(trait_ref) = stack.pop() {
- let anon_trait_ref = tcx.anonymize_late_bound_regions(trait_ref);
- if visited.insert(anon_trait_ref) {
- let super_predicates = tcx.super_predicates_that_define_assoc_type((
- trait_ref.def_id(),
- Some(assoc_name),
- ));
- for (super_predicate, _) in super_predicates.predicates {
- let bound_predicate = super_predicate.kind();
- let subst_predicate = super_predicate
- .subst_supertrait(tcx, &bound_predicate.rebind(trait_ref.skip_binder()));
- if let Some(binder) = subst_predicate.to_opt_poly_trait_ref() {
- stack.push(binder.value);
- }
- }
-
- return Some(trait_ref);
- }
- }
-
- return None;
- })
-}
-
///////////////////////////////////////////////////////////////////////////
// Other
///////////////////////////////////////////////////////////////////////////
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index f2b69da3f86b1..0935eb2bd7199 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -1,5 +1,4 @@
#![feature(bool_to_option)]
-#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(internal_output_capture)]
#![feature(nll)]
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index b7dc539c6d606..f34990a1a1037 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -759,7 +759,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
let is_const = match i {
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
- ast::ItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) => Self::is_sig_const(sig),
+ ast::ItemKind::Fn(_, ref sig, _, _) => Self::is_sig_const(sig),
_ => false,
};
self.run(is_const, |s| noop_visit_item_kind(i, s))
@@ -768,7 +768,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
fn flat_map_trait_item(&mut self, i: P) -> SmallVec<[P; 1]> {
let is_const = match i.kind {
ast::AssocItemKind::Const(..) => true,
- ast::AssocItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) => Self::is_sig_const(sig),
+ ast::AssocItemKind::Fn(_, ref sig, _, _) => Self::is_sig_const(sig),
_ => false,
};
self.run(is_const, |s| noop_flat_map_assoc_item(i, s))
diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml
index 90badd3d573a8..c56eb09b63471 100644
--- a/compiler/rustc_lint/Cargo.toml
+++ b/compiler/rustc_lint/Cargo.toml
@@ -19,6 +19,5 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_feature = { path = "../rustc_feature" }
rustc_index = { path = "../rustc_index" }
rustc_session = { path = "../rustc_session" }
-rustc_serialize = { path = "../rustc_serialize" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_parse_format = { path = "../rustc_parse_format" }
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 20f581625dc31..d0e44550ee6e7 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -328,18 +328,6 @@ impl UnsafeCode {
cx.struct_span_lint(UNSAFE_CODE, span, decorate);
}
-
- fn report_overriden_symbol_name(&self, cx: &EarlyContext<'_>, span: Span, msg: &str) {
- self.report_unsafe(cx, span, |lint| {
- lint.build(msg)
- .note(
- "the linker's behavior with multiple libraries exporting duplicate symbol \
- names is undefined and Rust cannot provide guarantees when you manually \
- override them",
- )
- .emit();
- })
- }
}
impl EarlyLintPass for UnsafeCode {
@@ -369,48 +357,16 @@ impl EarlyLintPass for UnsafeCode {
fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
match it.kind {
- ast::ItemKind::Trait(box ast::TraitKind(_, ast::Unsafe::Yes(_), ..)) => self
- .report_unsafe(cx, it.span, |lint| {
+ ast::ItemKind::Trait(_, ast::Unsafe::Yes(_), ..) => {
+ self.report_unsafe(cx, it.span, |lint| {
lint.build("declaration of an `unsafe` trait").emit()
- }),
-
- ast::ItemKind::Impl(box ast::ImplKind { unsafety: ast::Unsafe::Yes(_), .. }) => self
- .report_unsafe(cx, it.span, |lint| {
- lint.build("implementation of an `unsafe` trait").emit()
- }),
-
- ast::ItemKind::Fn(..) => {
- if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) {
- self.report_overriden_symbol_name(
- cx,
- attr.span,
- "declaration of a `no_mangle` function",
- );
- }
- if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::export_name) {
- self.report_overriden_symbol_name(
- cx,
- attr.span,
- "declaration of a function with `export_name`",
- );
- }
+ })
}
- ast::ItemKind::Static(..) => {
- if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) {
- self.report_overriden_symbol_name(
- cx,
- attr.span,
- "declaration of a `no_mangle` static",
- );
- }
- if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::export_name) {
- self.report_overriden_symbol_name(
- cx,
- attr.span,
- "declaration of a static with `export_name`",
- );
- }
+ ast::ItemKind::Impl { unsafety: ast::Unsafe::Yes(_), .. } => {
+ self.report_unsafe(cx, it.span, |lint| {
+ lint.build("implementation of an `unsafe` trait").emit()
+ })
}
_ => {}
@@ -916,7 +872,7 @@ declare_lint_pass!(
impl EarlyLintPass for AnonymousParameters {
fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
- if let ast::AssocItemKind::Fn(box FnKind(_, ref sig, _, _)) = it.kind {
+ if let ast::AssocItemKind::Fn(_, ref sig, _, _) = it.kind {
for arg in sig.decl.inputs.iter() {
if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind {
if ident.name == kw::Empty {
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index b8db51f590d84..8bd9dad785c4b 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -21,9 +21,7 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject};
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync;
-use rustc_errors::{
- add_elided_lifetime_in_path_suggestion, struct_span_err, Applicability, SuggestionStyle,
-};
+use rustc_errors::{add_elided_lifetime_in_path_suggestion, struct_span_err, Applicability};
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::{CrateNum, DefId};
@@ -34,15 +32,13 @@ use rustc_middle::middle::stability;
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};
-use rustc_serialize::json::Json;
-use rustc_session::lint::{BuiltinLintDiagnostics, ExternDepSpec};
+use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
use rustc_session::Session;
use rustc_session::SessionLintStore;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
use rustc_target::abi::LayoutOf;
-use tracing::debug;
use std::cell::Cell;
use std::slice;
@@ -340,20 +336,6 @@ impl LintStore {
}
}
- /// True if this symbol represents a lint group name.
- pub fn is_lint_group(&self, lint_name: Symbol) -> bool {
- debug!(
- "is_lint_group(lint_name={:?}, lint_groups={:?})",
- lint_name,
- self.lint_groups.keys().collect::>()
- );
- let lint_name_str = &*lint_name.as_str();
- self.lint_groups.contains_key(&lint_name_str) || {
- let warnings_name_str = crate::WARNINGS.name_lower();
- lint_name_str == &*warnings_name_str
- }
- }
-
/// Checks the name of a lint for its existence, and whether it was
/// renamed or removed. Generates a DiagnosticBuilder containing a
/// warning for renamed and removed lints. This is over both lint
@@ -639,33 +621,6 @@ pub trait LintContext: Sized {
db.span_label(span, "ABI should be specified here");
db.help(&format!("the default ABI is {}", default_abi.name()));
}
- BuiltinLintDiagnostics::LegacyDeriveHelpers(span) => {
- db.span_label(span, "the attribute is introduced here");
- }
- BuiltinLintDiagnostics::ExternDepSpec(krate, loc) => {
- let json = match loc {
- ExternDepSpec::Json(json) => {
- db.help(&format!("remove unnecessary dependency `{}`", krate));
- json
- }
- ExternDepSpec::Raw(raw) => {
- db.help(&format!("remove unnecessary dependency `{}` at `{}`", krate, raw));
- db.span_suggestion_with_style(
- DUMMY_SP,
- "raw extern location",
- raw.clone(),
- Applicability::Unspecified,
- SuggestionStyle::CompletelyHidden,
- );
- Json::String(raw)
- }
- };
- db.tool_only_suggestion_with_metadata(
- "json extern location",
- Applicability::Unspecified,
- json
- );
- }
}
// Rewrap `db`, and pass control to the user.
decorate(LintDiagnosticBuilder::new(db));
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 231edf442eb00..e36af2349360f 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -143,14 +143,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
run_early_pass!(self, check_fn, fk, span, id);
self.check_id(id);
ast_visit::walk_fn(self, fk, span);
-
- // Explicitly check for lints associated with 'closure_id', since
- // it does not have a corresponding AST node
- if let ast_visit::FnKind::Fn(_, _, sig, _, _) = fk {
- if let ast::Async::Yes { closure_id, .. } = sig.header.asyncness {
- self.check_id(closure_id);
- }
- }
run_early_pass!(self, check_fn_post, fk, span, id);
}
@@ -216,14 +208,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
fn visit_expr_post(&mut self, e: &'a ast::Expr) {
run_early_pass!(self, check_expr_post, e);
-
- // Explicitly check for lints associated with 'closure_id', since
- // it does not have a corresponding AST node
- match e.kind {
- ast::ExprKind::Closure(_, ast::Async::Yes { closure_id, .. }, ..)
- | ast::ExprKind::Async(_, closure_id, ..) => self.check_id(closure_id),
- _ => {}
- }
}
fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) {
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 26e536e8f1ddb..af5972c6c81c7 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -2,7 +2,7 @@
//! Clippy.
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc_ast::{ImplKind, Item, ItemKind};
+use rustc_ast::{Item, ItemKind};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
@@ -243,7 +243,7 @@ declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]);
impl EarlyLintPass for LintPassImpl {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
- if let ItemKind::Impl(box ImplKind { of_trait: Some(lint_pass), .. }) = &item.kind {
+ if let ItemKind::Impl { of_trait: Some(lint_pass), .. } = &item.kind {
if let Some(last) = lint_pass.path.segments.last() {
if last.ident.name == sym::LintPass {
let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 1fc2bd0916757..18cd25e5d2aa3 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -5,7 +5,7 @@ use rustc_ast::attr;
use rustc_ast::unwrap_or;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
+use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_hir::{intravisit, HirId};
@@ -17,15 +17,11 @@ use rustc_middle::lint::{
};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
-use rustc_session::lint::{
- builtin::{self, FORBIDDEN_LINT_GROUPS},
- Level, Lint, LintId,
-};
+use rustc_session::lint::{builtin, Level, Lint, LintId};
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP};
-use tracing::debug;
use std::cmp;
@@ -55,7 +51,6 @@ pub struct LintLevelsBuilder<'s> {
id_to_set: FxHashMap,
cur: u32,
warn_about_weird_lints: bool,
- store: &'s LintStore,
}
pub struct BuilderPush {
@@ -64,14 +59,13 @@ pub struct BuilderPush {
}
impl<'s> LintLevelsBuilder<'s> {
- pub fn new(sess: &'s Session, warn_about_weird_lints: bool, store: &'s LintStore) -> Self {
+ pub fn new(sess: &'s Session, warn_about_weird_lints: bool, store: &LintStore) -> Self {
let mut builder = LintLevelsBuilder {
sess,
sets: LintLevelSets::new(),
cur: 0,
id_to_set: Default::default(),
warn_about_weird_lints,
- store,
};
builder.process_command_line(sess, store);
assert_eq!(builder.sets.list.len(), 1);
@@ -126,75 +120,36 @@ impl<'s> LintLevelsBuilder<'s> {
if let (Level::Forbid, old_src) =
self.sets.get_lint_level(id.lint, self.cur, Some(&specs), &self.sess)
{
- // Backwards compatibility check:
- //
- // We used to not consider `forbid(lint_group)`
- // as preventing `allow(lint)` for some lint `lint` in
- // `lint_group`. For now, issue a future-compatibility
- // warning for this case.
- let id_name = id.lint.name_lower();
- let fcw_warning = match old_src {
- LintLevelSource::Default => false,
- LintLevelSource::Node(symbol, _, _) => self.store.is_lint_group(symbol),
- LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol),
- };
- debug!(
- "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}",
- fcw_warning, specs, old_src, id_name
+ let mut diag_builder = struct_span_err!(
+ self.sess,
+ src.span(),
+ E0453,
+ "{}({}) incompatible with previous forbid",
+ level.as_str(),
+ src.name(),
);
-
- let decorate_diag_builder = |mut diag_builder: DiagnosticBuilder<'_>| {
- diag_builder.span_label(src.span(), "overruled by previous forbid");
- match old_src {
- LintLevelSource::Default => {
- diag_builder.note(&format!(
- "`forbid` lint level is the default for {}",
- id.to_string()
- ));
- }
- LintLevelSource::Node(_, forbid_source_span, reason) => {
- diag_builder.span_label(forbid_source_span, "`forbid` level set here");
- if let Some(rationale) = reason {
- diag_builder.note(&rationale.as_str());
- }
- }
- LintLevelSource::CommandLine(_, _) => {
- diag_builder.note("`forbid` lint level was set on command line");
+ diag_builder.span_label(src.span(), "overruled by previous forbid");
+ match old_src {
+ LintLevelSource::Default => {
+ diag_builder.note(&format!(
+ "`forbid` lint level is the default for {}",
+ id.to_string()
+ ));
+ }
+ LintLevelSource::Node(_, forbid_source_span, reason) => {
+ diag_builder.span_label(forbid_source_span, "`forbid` level set here");
+ if let Some(rationale) = reason {
+ diag_builder.note(&rationale.as_str());
}
}
- diag_builder.emit();
- };
- if !fcw_warning {
- let diag_builder = struct_span_err!(
- self.sess,
- src.span(),
- E0453,
- "{}({}) incompatible with previous forbid",
- level.as_str(),
- src.name(),
- );
- decorate_diag_builder(diag_builder);
- } else {
- self.struct_lint(
- FORBIDDEN_LINT_GROUPS,
- Some(src.span().into()),
- |diag_builder| {
- let diag_builder = diag_builder.build(&format!(
- "{}({}) incompatible with previous forbid",
- level.as_str(),
- src.name(),
- ));
- decorate_diag_builder(diag_builder);
- },
- );
+ LintLevelSource::CommandLine(_, _) => {
+ diag_builder.note("`forbid` lint level was set on command line");
+ }
}
+ diag_builder.emit();
- // Retain the forbid lint level, unless we are
- // issuing a FCW. In the FCW case, we want to
- // respect the new setting.
- if !fcw_warning {
- return;
- }
+ // Retain the forbid lint level
+ return;
}
}
specs.insert(id, (level, src));
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 638b73c27a8d7..2336b52619ab8 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -30,7 +30,6 @@
#![feature(array_windows)]
#![feature(bool_to_option)]
#![feature(box_syntax)]
-#![feature(box_patterns)]
#![feature(crate_visibility_modifier)]
#![feature(iter_order_by)]
#![feature(never_type)]
@@ -55,8 +54,8 @@ mod late;
mod levels;
mod methods;
mod non_ascii_idents;
-mod non_fmt_panic;
mod nonstandard_style;
+mod panic_fmt;
mod passes;
mod redundant_semicolon;
mod traits;
@@ -81,8 +80,8 @@ use builtin::*;
use internal::*;
use methods::*;
use non_ascii_idents::*;
-use non_fmt_panic::NonPanicFmt;
use nonstandard_style::*;
+use panic_fmt::PanicFmt;
use redundant_semicolon::*;
use traits::*;
use types::*;
@@ -169,7 +168,7 @@ macro_rules! late_lint_passes {
ClashingExternDeclarations: ClashingExternDeclarations::new(),
DropTraitConstraints: DropTraitConstraints,
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
- NonPanicFmt: NonPanicFmt,
+ PanicFmt: PanicFmt,
]
);
};
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
deleted file mode 100644
index e98297b692c92..0000000000000
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ /dev/null
@@ -1,197 +0,0 @@
-use crate::{LateContext, LateLintPass, LintContext};
-use rustc_ast as ast;
-use rustc_errors::{pluralize, Applicability};
-use rustc_hir as hir;
-use rustc_middle::ty;
-use rustc_parse_format::{ParseMode, Parser, Piece};
-use rustc_span::{sym, symbol::kw, InnerSpan, Span, Symbol};
-
-declare_lint! {
- /// The `non_fmt_panic` lint detects `panic!(..)` invocations where the first
- /// argument is not a formatting string.
- ///
- /// ### Example
- ///
- /// ```rust,no_run
- /// panic!("{}");
- /// panic!(123);
- /// ```
- ///
- /// {{produces}}
- ///
- /// ### Explanation
- ///
- /// In Rust 2018 and earlier, `panic!(x)` directly uses `x` as the message.
- /// That means that `panic!("{}")` panics with the message `"{}"` instead
- /// of using it as a formatting string, and `panic!(123)` will panic with
- /// an `i32` as message.
- ///
- /// Rust 2021 always interprets the first argument as format string.
- NON_FMT_PANIC,
- Warn,
- "detect single-argument panic!() invocations in which the argument is not a format string",
- report_in_external_macro
-}
-
-declare_lint_pass!(NonPanicFmt => [NON_FMT_PANIC]);
-
-impl<'tcx> LateLintPass<'tcx> for NonPanicFmt {
- fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
- if let hir::ExprKind::Call(f, [arg]) = &expr.kind {
- if let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind() {
- if Some(def_id) == cx.tcx.lang_items().begin_panic_fn()
- || Some(def_id) == cx.tcx.lang_items().panic_fn()
- || Some(def_id) == cx.tcx.lang_items().panic_str()
- {
- if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id {
- if cx.tcx.is_diagnostic_item(sym::std_panic_2015_macro, id)
- || cx.tcx.is_diagnostic_item(sym::core_panic_2015_macro, id)
- {
- check_panic(cx, f, arg);
- }
- }
- }
- }
- }
- }
-}
-
-fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tcx hir::Expr<'tcx>) {
- if let hir::ExprKind::Lit(lit) = &arg.kind {
- if let ast::LitKind::Str(sym, _) = lit.node {
- // The argument is a string literal.
- check_panic_str(cx, f, arg, &sym.as_str());
- return;
- }
- }
-
- // The argument is *not* a string literal.
-
- let (span, panic) = panic_call(cx, f);
-
- cx.struct_span_lint(NON_FMT_PANIC, arg.span, |lint| {
- let mut l = lint.build("panic message is not a string literal");
- l.note("this is no longer accepted in Rust 2021");
- if span.contains(arg.span) {
- l.span_suggestion_verbose(
- arg.span.shrink_to_lo(),
- "add a \"{}\" format string to Display the message",
- "\"{}\", ".into(),
- Applicability::MaybeIncorrect,
- );
- if panic == sym::std_panic_macro {
- l.span_suggestion_verbose(
- span.until(arg.span),
- "or use std::panic::panic_any instead",
- "std::panic::panic_any(".into(),
- Applicability::MachineApplicable,
- );
- }
- }
- l.emit();
- });
-}
-
-fn check_panic_str<'tcx>(
- cx: &LateContext<'tcx>,
- f: &'tcx hir::Expr<'tcx>,
- arg: &'tcx hir::Expr<'tcx>,
- fmt: &str,
-) {
- if !fmt.contains(&['{', '}'][..]) {
- // No brace, no problem.
- return;
- }
-
- let fmt_span = arg.span.source_callsite();
-
- let (snippet, style) = match cx.sess().parse_sess.source_map().span_to_snippet(fmt_span) {
- Ok(snippet) => {
- // Count the number of `#`s between the `r` and `"`.
- let style = snippet.strip_prefix('r').and_then(|s| s.find('"'));
- (Some(snippet), style)
- }
- Err(_) => (None, None),
- };
-
- let mut fmt_parser =
- Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format);
- let n_arguments = (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
-
- let (span, _) = panic_call(cx, f);
-
- if n_arguments > 0 && fmt_parser.errors.is_empty() {
- let arg_spans: Vec<_> = match &fmt_parser.arg_places[..] {
- [] => vec![fmt_span],
- v => v.iter().map(|span| fmt_span.from_inner(*span)).collect(),
- };
- cx.struct_span_lint(NON_FMT_PANIC, arg_spans, |lint| {
- let mut l = lint.build(match n_arguments {
- 1 => "panic message contains an unused formatting placeholder",
- _ => "panic message contains unused formatting placeholders",
- });
- l.note("this message is not used as a format string when given without arguments, but will be in Rust 2021");
- if span.contains(arg.span) {
- l.span_suggestion(
- arg.span.shrink_to_hi(),
- &format!("add the missing argument{}", pluralize!(n_arguments)),
- ", ...".into(),
- Applicability::HasPlaceholders,
- );
- l.span_suggestion(
- arg.span.shrink_to_lo(),
- "or add a \"{}\" format string to use the message literally",
- "\"{}\", ".into(),
- Applicability::MachineApplicable,
- );
- }
- l.emit();
- });
- } else {
- let brace_spans: Option> =
- snippet.filter(|s| s.starts_with('"') || s.starts_with("r#")).map(|s| {
- s.char_indices()
- .filter(|&(_, c)| c == '{' || c == '}')
- .map(|(i, _)| fmt_span.from_inner(InnerSpan { start: i, end: i + 1 }))
- .collect()
- });
- let msg = match &brace_spans {
- Some(v) if v.len() == 1 => "panic message contains a brace",
- _ => "panic message contains braces",
- };
- cx.struct_span_lint(NON_FMT_PANIC, brace_spans.unwrap_or(vec![span]), |lint| {
- let mut l = lint.build(msg);
- l.note("this message is not used as a format string, but will be in Rust 2021");
- if span.contains(arg.span) {
- l.span_suggestion(
- arg.span.shrink_to_lo(),
- "add a \"{}\" format string to use the message literally",
- "\"{}\", ".into(),
- Applicability::MachineApplicable,
- );
- }
- l.emit();
- });
- }
-}
-
-fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span, Symbol) {
- let mut expn = f.span.ctxt().outer_expn_data();
-
- let mut panic_macro = kw::Empty;
-
- // Unwrap more levels of macro expansion, as panic_2015!()
- // was likely expanded from panic!() and possibly from
- // [debug_]assert!().
- for &i in
- &[sym::std_panic_macro, sym::core_panic_macro, sym::assert_macro, sym::debug_assert_macro]
- {
- let parent = expn.call_site.ctxt().outer_expn_data();
- if parent.macro_def_id.map_or(false, |id| cx.tcx.is_diagnostic_item(i, id)) {
- expn = parent;
- panic_macro = i;
- }
- }
-
- (expn.call_site, panic_macro)
-}
diff --git a/compiler/rustc_lint/src/panic_fmt.rs b/compiler/rustc_lint/src/panic_fmt.rs
new file mode 100644
index 0000000000000..4a6aca72acbbe
--- /dev/null
+++ b/compiler/rustc_lint/src/panic_fmt.rs
@@ -0,0 +1,155 @@
+use crate::{LateContext, LateLintPass, LintContext};
+use rustc_ast as ast;
+use rustc_errors::{pluralize, Applicability};
+use rustc_hir as hir;
+use rustc_middle::ty;
+use rustc_parse_format::{ParseMode, Parser, Piece};
+use rustc_span::{sym, InnerSpan};
+
+declare_lint! {
+ /// The `panic_fmt` lint detects `panic!("..")` with `{` or `}` in the string literal.
+ ///
+ /// ### Example
+ ///
+ /// ```rust,no_run
+ /// panic!("{}");
+ /// ```
+ ///
+ /// {{produces}}
+ ///
+ /// ### Explanation
+ ///
+ /// In Rust 2018 and earlier, `panic!("{}")` panics with the message `"{}"`,
+ /// as a `panic!()` invocation with a single argument does not use `format_args!()`.
+ /// Rust 2021 interprets this string as format string, which breaks this.
+ PANIC_FMT,
+ Warn,
+ "detect braces in single-argument panic!() invocations",
+ report_in_external_macro
+}
+
+declare_lint_pass!(PanicFmt => [PANIC_FMT]);
+
+impl<'tcx> LateLintPass<'tcx> for PanicFmt {
+ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
+ if let hir::ExprKind::Call(f, [arg]) = &expr.kind {
+ if let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind() {
+ if Some(def_id) == cx.tcx.lang_items().begin_panic_fn()
+ || Some(def_id) == cx.tcx.lang_items().panic_fn()
+ {
+ check_panic(cx, f, arg);
+ }
+ }
+ }
+ }
+}
+
+fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tcx hir::Expr<'tcx>) {
+ if let hir::ExprKind::Lit(lit) = &arg.kind {
+ if let ast::LitKind::Str(sym, _) = lit.node {
+ let mut expn = f.span.ctxt().outer_expn_data();
+ if let Some(id) = expn.macro_def_id {
+ if cx.tcx.is_diagnostic_item(sym::std_panic_2015_macro, id)
+ || cx.tcx.is_diagnostic_item(sym::core_panic_2015_macro, id)
+ {
+ let fmt = sym.as_str();
+ if !fmt.contains(&['{', '}'][..]) {
+ return;
+ }
+
+ let fmt_span = arg.span.source_callsite();
+
+ let (snippet, style) =
+ match cx.sess().parse_sess.source_map().span_to_snippet(fmt_span) {
+ Ok(snippet) => {
+ // Count the number of `#`s between the `r` and `"`.
+ let style = snippet.strip_prefix('r').and_then(|s| s.find('"'));
+ (Some(snippet), style)
+ }
+ Err(_) => (None, None),
+ };
+
+ let mut fmt_parser =
+ Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format);
+ let n_arguments =
+ (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
+
+ // Unwrap more levels of macro expansion, as panic_2015!()
+ // was likely expanded from panic!() and possibly from
+ // [debug_]assert!().
+ for &assert in &[
+ sym::std_panic_macro,
+ sym::core_panic_macro,
+ sym::assert_macro,
+ sym::debug_assert_macro,
+ ] {
+ let parent = expn.call_site.ctxt().outer_expn_data();
+ if parent
+ .macro_def_id
+ .map_or(false, |id| cx.tcx.is_diagnostic_item(assert, id))
+ {
+ expn = parent;
+ }
+ }
+
+ if n_arguments > 0 && fmt_parser.errors.is_empty() {
+ let arg_spans: Vec<_> = match &fmt_parser.arg_places[..] {
+ [] => vec![fmt_span],
+ v => v.iter().map(|span| fmt_span.from_inner(*span)).collect(),
+ };
+ cx.struct_span_lint(PANIC_FMT, arg_spans, |lint| {
+ let mut l = lint.build(match n_arguments {
+ 1 => "panic message contains an unused formatting placeholder",
+ _ => "panic message contains unused formatting placeholders",
+ });
+ l.note("this message is not used as a format string when given without arguments, but will be in a future Rust edition");
+ if expn.call_site.contains(arg.span) {
+ l.span_suggestion(
+ arg.span.shrink_to_hi(),
+ &format!("add the missing argument{}", pluralize!(n_arguments)),
+ ", ...".into(),
+ Applicability::HasPlaceholders,
+ );
+ l.span_suggestion(
+ arg.span.shrink_to_lo(),
+ "or add a \"{}\" format string to use the message literally",
+ "\"{}\", ".into(),
+ Applicability::MachineApplicable,
+ );
+ }
+ l.emit();
+ });
+ } else {
+ let brace_spans: Option> = snippet
+ .filter(|s| s.starts_with('"') || s.starts_with("r#"))
+ .map(|s| {
+ s.char_indices()
+ .filter(|&(_, c)| c == '{' || c == '}')
+ .map(|(i, _)| {
+ fmt_span.from_inner(InnerSpan { start: i, end: i + 1 })
+ })
+ .collect()
+ });
+ let msg = match &brace_spans {
+ Some(v) if v.len() == 1 => "panic message contains a brace",
+ _ => "panic message contains braces",
+ };
+ cx.struct_span_lint(PANIC_FMT, brace_spans.unwrap_or(vec![expn.call_site]), |lint| {
+ let mut l = lint.build(msg);
+ l.note("this message is not used as a format string, but will be in a future Rust edition");
+ if expn.call_site.contains(arg.span) {
+ l.span_suggestion(
+ arg.span.shrink_to_lo(),
+ "add a \"{}\" format string to use the message literally",
+ "\"{}\", ".into(),
+ Applicability::MachineApplicable,
+ );
+ }
+ l.emit();
+ });
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index f0a5ea150b719..199be00990761 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -1,5 +1,4 @@
// ignore-tidy-filelength
-
//! Some lints that are built in to the compiler.
//!
//! These are the built-in lints that are emitted direct in the main
@@ -10,42 +9,6 @@ use crate::{declare_lint, declare_lint_pass};
use rustc_span::edition::Edition;
use rustc_span::symbol::sym;
-declare_lint! {
- /// The `forbidden_lint_groups` lint detects violations of
- /// `forbid` applied to a lint group. Due to a bug in the compiler,
- /// these used to be overlooked entirely. They now generate a warning.
- ///
- /// ### Example
- ///
- /// ```rust
- /// #![forbid(warnings)]
- /// #![deny(bad_style)]
- ///
- /// fn main() {}
- /// ```
- ///
- /// {{produces}}
- ///
- /// ### Recommended fix
- ///
- /// If your crate is using `#![forbid(warnings)]`,
- /// we recommend that you change to `#![deny(warnings)]`.
- ///
- /// ### Explanation
- ///
- /// Due to a compiler bug, applying `forbid` to lint groups
- /// previously had no effect. The bug is now fixed but instead of
- /// enforcing `forbid` we issue this future-compatibility warning
- /// to avoid breaking existing crates.
- pub FORBIDDEN_LINT_GROUPS,
- Warn,
- "applying forbid to lint-groups",
- @future_incompatible = FutureIncompatibleInfo {
- reference: "issue #81670 ",
- edition: None,
- };
-}
-
declare_lint! {
/// The `ill_formed_attribute_input` lint detects ill-formed attribute
/// inputs that were previously accepted and used in practice.
@@ -292,10 +255,6 @@ declare_lint! {
pub CONST_ERR,
Deny,
"constant evaluation encountered erroneous expression",
- @future_incompatible = FutureIncompatibleInfo {
- reference: "issue #71800 ",
- edition: None,
- };
report_in_external_macro
}
@@ -2921,57 +2880,10 @@ declare_lint! {
};
}
-declare_lint! {
- /// The `legacy_derive_helpers` lint detects derive helper attributes
- /// that are used before they are introduced.
- ///
- /// ### Example
- ///
- /// ```rust,ignore (needs extern crate)
- /// #[serde(rename_all = "camelCase")]
- /// #[derive(Deserialize)]
- /// struct S { /* fields */ }
- /// ```
- ///
- /// produces:
- ///
- /// ```text
- /// warning: derive helper attribute is used before it is introduced
- /// --> $DIR/legacy-derive-helpers.rs:1:3
- /// |
- /// 1 | #[serde(rename_all = "camelCase")]
- /// | ^^^^^
- /// ...
- /// 2 | #[derive(Deserialize)]
- /// | ----------- the attribute is introduced here
- /// ```
- ///
- /// ### Explanation
- ///
- /// Attributes like this work for historical reasons, but attribute expansion works in
- /// left-to-right order in general, so, to resolve `#[serde]`, compiler has to try to "look
- /// into the future" at not yet expanded part of the item , but such attempts are not always
- /// reliable.
- ///
- /// To fix the warning place the helper attribute after its corresponding derive.
- /// ```rust,ignore (needs extern crate)
- /// #[derive(Deserialize)]
- /// #[serde(rename_all = "camelCase")]
- /// struct S { /* fields */ }
- /// ```
- pub LEGACY_DERIVE_HELPERS,
- Warn,
- "detects derive helper attributes that are used before they are introduced",
- @future_incompatible = FutureIncompatibleInfo {
- reference: "issue #79202 ",
- };
-}
-
declare_lint_pass! {
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
HardwiredLints => [
- FORBIDDEN_LINT_GROUPS,
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
ARITHMETIC_OVERFLOW,
UNCONDITIONAL_PANIC,
@@ -3057,7 +2969,6 @@ declare_lint_pass! {
MISSING_ABI,
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
DISJOINT_CAPTURE_DROP_REORDER,
- LEGACY_DERIVE_HELPERS,
]
}
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 4c7d3f6c8c072..9d60a51a0afb3 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -4,7 +4,6 @@ extern crate rustc_macros;
pub use self::Level::*;
use rustc_ast::node_id::{NodeId, NodeMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
-use rustc_serialize::json::Json;
use rustc_span::edition::Edition;
use rustc_span::{sym, symbol::Ident, MultiSpan, Span, Symbol};
use rustc_target::spec::abi::Abi;
@@ -240,13 +239,6 @@ impl ToStableHashKey for LintId {
}
}
-// Duplicated from rustc_session::config::ExternDepSpec to avoid cyclic dependency
-#[derive(PartialEq)]
-pub enum ExternDepSpec {
- Json(Json),
- Raw(String),
-}
-
// This could be a closure, but then implementing derive trait
// becomes hacky (and it gets allocated).
#[derive(PartialEq)]
@@ -264,8 +256,6 @@ pub enum BuiltinLintDiagnostics {
MissingAbi(Span, Abi),
UnusedDocComment(Span),
PatternsInFnsWithoutBody(Span, Ident),
- LegacyDeriveHelpers(Span),
- ExternDepSpec(String, ExternDepSpec),
}
/// Lints that are buffered up early on in the `Session` before the
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 4118e93074563..1d89fc8049660 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -216,14 +216,6 @@ extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
Call->addAttribute(Index, Attr);
}
-extern "C" void LLVMRustAddCallSiteAttrString(LLVMValueRef Instr, unsigned Index,
- const char *Name) {
- CallBase *Call = unwrap(Instr);
- Attribute Attr = Attribute::get(Call->getContext(), Name);
- Call->addAttribute(Index, Attr);
-}
-
-
extern "C" void LLVMRustAddAlignmentCallSiteAttr(LLVMValueRef Instr,
unsigned Index,
uint32_t Bytes) {
diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs
index bd20c7689ea2e..d264462bf0895 100644
--- a/compiler/rustc_macros/src/query.rs
+++ b/compiler/rustc_macros/src/query.rs
@@ -189,6 +189,25 @@ impl Parse for List {
}
}
+/// A named group containing queries.
+///
+/// For now, the name is not used any more, but the capability remains interesting for future
+/// developments of the query system.
+struct Group {
+ #[allow(unused)]
+ name: Ident,
+ queries: List,
+}
+
+impl Parse for Group {
+ fn parse(input: ParseStream<'_>) -> Result {
+ let name: Ident = input.parse()?;
+ let content;
+ braced!(content in input);
+ Ok(Group { name, queries: content.parse()? })
+ }
+}
+
struct QueryModifiers {
/// The description of the query.
desc: (Option, Punctuated),
@@ -417,8 +436,8 @@ fn add_query_description_impl(
fn describe(
#tcx: TyCtxt<'tcx>,
#key: #arg,
- ) -> String {
- ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc))
+ ) -> Cow<'static, str> {
+ ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc).into())
}
};
@@ -431,70 +450,72 @@ fn add_query_description_impl(
}
pub fn rustc_queries(input: TokenStream) -> TokenStream {
- let queries = parse_macro_input!(input as List);
+ let groups = parse_macro_input!(input as List);
let mut query_stream = quote! {};
let mut query_description_stream = quote! {};
let mut dep_node_def_stream = quote! {};
let mut cached_queries = quote! {};
- for mut query in queries.0 {
- let modifiers = process_modifiers(&mut query);
- let name = &query.name;
- let arg = &query.arg;
- let result_full = &query.result;
- let result = match query.result {
- ReturnType::Default => quote! { -> () },
- _ => quote! { #result_full },
- };
+ for group in groups.0 {
+ for mut query in group.queries.0 {
+ let modifiers = process_modifiers(&mut query);
+ let name = &query.name;
+ let arg = &query.arg;
+ let result_full = &query.result;
+ let result = match query.result {
+ ReturnType::Default => quote! { -> () },
+ _ => quote! { #result_full },
+ };
- if modifiers.cache.is_some() {
- cached_queries.extend(quote! {
- #name,
- });
- }
+ if modifiers.cache.is_some() {
+ cached_queries.extend(quote! {
+ #name,
+ });
+ }
- let mut attributes = Vec::new();
+ let mut attributes = Vec::new();
- // Pass on the fatal_cycle modifier
- if modifiers.fatal_cycle {
- attributes.push(quote! { fatal_cycle });
- };
- // Pass on the storage modifier
- if let Some(ref ty) = modifiers.storage {
- attributes.push(quote! { storage(#ty) });
- };
- // Pass on the cycle_delay_bug modifier
- if modifiers.cycle_delay_bug {
- attributes.push(quote! { cycle_delay_bug });
- };
- // Pass on the no_hash modifier
- if modifiers.no_hash {
- attributes.push(quote! { no_hash });
- };
- // Pass on the anon modifier
- if modifiers.anon {
- attributes.push(quote! { anon });
- };
- // Pass on the eval_always modifier
- if modifiers.eval_always {
- attributes.push(quote! { eval_always });
- };
+ // Pass on the fatal_cycle modifier
+ if modifiers.fatal_cycle {
+ attributes.push(quote! { fatal_cycle });
+ };
+ // Pass on the storage modifier
+ if let Some(ref ty) = modifiers.storage {
+ attributes.push(quote! { storage(#ty) });
+ };
+ // Pass on the cycle_delay_bug modifier
+ if modifiers.cycle_delay_bug {
+ attributes.push(quote! { cycle_delay_bug });
+ };
+ // Pass on the no_hash modifier
+ if modifiers.no_hash {
+ attributes.push(quote! { no_hash });
+ };
+ // Pass on the anon modifier
+ if modifiers.anon {
+ attributes.push(quote! { anon });
+ };
+ // Pass on the eval_always modifier
+ if modifiers.eval_always {
+ attributes.push(quote! { eval_always });
+ };
- let attribute_stream = quote! {#(#attributes),*};
- let doc_comments = query.doc_comments.iter();
- // Add the query to the group
- query_stream.extend(quote! {
- #(#doc_comments)*
- [#attribute_stream] fn #name(#arg) #result,
- });
+ let attribute_stream = quote! {#(#attributes),*};
+ let doc_comments = query.doc_comments.iter();
+ // Add the query to the group
+ query_stream.extend(quote! {
+ #(#doc_comments)*
+ [#attribute_stream] fn #name(#arg) #result,
+ });
- // Create a dep node for the query
- dep_node_def_stream.extend(quote! {
- [#attribute_stream] #name(#arg),
- });
+ // Create a dep node for the query
+ dep_node_def_stream.extend(quote! {
+ [#attribute_stream] #name(#arg),
+ });
- add_query_description_impl(&query, modifiers, &mut query_description_stream);
+ add_query_description_impl(&query, modifiers, &mut query_description_stream);
+ }
}
TokenStream::from(quote! {
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 63c6f369eb685..e3fbd1a2b29ea 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -16,9 +16,8 @@ use rustc_index::vec::IndexVec;
use rustc_middle::middle::cstore::{CrateDepKind, CrateSource, ExternCrate};
use rustc_middle::middle::cstore::{ExternCrateSource, MetadataLoaderDyn};
use rustc_middle::ty::TyCtxt;
-use rustc_serialize::json::ToJson;
use rustc_session::config::{self, CrateType, ExternLocation};
-use rustc_session::lint::{self, BuiltinLintDiagnostics, ExternDepSpec};
+use rustc_session::lint;
use rustc_session::output::validate_crate_name;
use rustc_session::search_paths::PathKind;
use rustc_session::{CrateDisambiguator, Session};
@@ -28,7 +27,6 @@ use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::{PanicStrategy, TargetTriple};
use proc_macro::bridge::client::ProcMacro;
-use std::collections::BTreeMap;
use std::path::Path;
use std::{cmp, env};
use tracing::{debug, info};
@@ -873,25 +871,8 @@ impl<'a> CrateLoader<'a> {
// Don't worry about pathless `--extern foo` sysroot references
continue;
}
- if self.used_extern_options.contains(&Symbol::intern(name)) {
- continue;
- }
-
- // Got a real unused --extern
- let diag = match self.sess.opts.extern_dep_specs.get(name) {
- Some(loc) => BuiltinLintDiagnostics::ExternDepSpec(name.clone(), loc.into()),
- None => {
- // If we don't have a specific location, provide a json encoding of the `--extern`
- // option.
- let meta: BTreeMap =
- std::iter::once(("name".to_string(), name.to_string())).collect();
- BuiltinLintDiagnostics::ExternDepSpec(
- name.clone(),
- ExternDepSpec::Json(meta.to_json()),
- )
- }
- };
- self.sess.parse_sess.buffer_lint_with_diagnostic(
+ if !self.used_extern_options.contains(&Symbol::intern(name)) {
+ self.sess.parse_sess.buffer_lint(
lint::builtin::UNUSED_CRATE_DEPENDENCIES,
span,
ast::CRATE_NODE_ID,
@@ -900,8 +881,8 @@ impl<'a> CrateLoader<'a> {
name,
self.local_crate_name,
name),
- diag,
);
+ }
}
}
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 14ca51008bec5..3961adacecae8 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -2,15 +2,15 @@ use crate::rmeta::table::{FixedSizeEncoding, TableBuilder};
use crate::rmeta::*;
use rustc_data_structures::fingerprint::{Fingerprint, FingerprintEncoder};
-use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
+use rustc_data_structures::sync::{join, Lrc};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind};
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::DefPathData;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
use rustc_hir::lang_items;
use rustc_hir::{AnonConst, GenericParamKind};
use rustc_index::bit_set::GrowableBitSet;
@@ -65,6 +65,11 @@ pub(super) struct EncodeContext<'a, 'tcx> {
required_source_files: Option>,
is_proc_macro: bool,
hygiene_ctxt: &'a HygieneEncodeContext,
+
+ // Determines if MIR used for code generation will be included in the crate
+ // metadata. When emitting only metadata (e.g., cargo check), we can avoid
+ // generating optimized MIR altogether.
+ emit_codegen_mir: bool,
}
/// If the current crate is a proc-macro, returns early with `Lazy:empty()`.
@@ -572,11 +577,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let tcx = self.tcx;
- // Encode MIR.
- i = self.position();
- self.encode_mir();
- let mir_bytes = self.position() - i;
-
// Encode the items.
i = self.position();
self.encode_def_ids();
@@ -704,7 +704,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
println!(" exp. symbols bytes: {}", exported_symbols_bytes);
println!(" def-path table bytes: {}", def_path_table_bytes);
println!(" proc-macro-data-bytes: {}", proc_macro_data_bytes);
- println!(" mir bytes: {}", mir_bytes);
println!(" item bytes: {}", item_bytes);
println!(" table bytes: {}", tables_bytes);
println!(" hygiene bytes: {}", hygiene_bytes);
@@ -786,53 +785,6 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
}
}
-/// Whether we should encode MIR.
-///
-/// Computing, optimizing and encoding the MIR is a relatively expensive operation.
-/// We want to avoid this work when not required. Therefore:
-/// - we only compute `mir_for_ctfe` on items with const-eval semantics;
-/// - we skip `optimized_mir` for check runs.
-///
-/// Return a pair, resp. for CTFE and for LLVM.
-fn should_encode_mir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> (bool, bool) {
- match tcx.def_kind(def_id) {
- // Constructors
- DefKind::Ctor(_, _) => {
- let mir_opt_base = tcx.sess.opts.output_types.should_codegen()
- || tcx.sess.opts.debugging_opts.always_encode_mir;
- (true, mir_opt_base)
- }
- // Constants
- DefKind::AnonConst | DefKind::AssocConst | DefKind::Static | DefKind::Const => {
- (true, false)
- }
- // Full-fledged functions
- DefKind::AssocFn | DefKind::Fn => {
- let generics = tcx.generics_of(def_id);
- let needs_inline = (generics.requires_monomorphization(tcx)
- || tcx.codegen_fn_attrs(def_id).requests_inline())
- && tcx.sess.opts.output_types.should_codegen();
- // Only check the presence of the `const` modifier.
- let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id());
- let always_encode_mir = tcx.sess.opts.debugging_opts.always_encode_mir;
- (is_const_fn, needs_inline || always_encode_mir)
- }
- // Closures can't be const fn.
- DefKind::Closure => {
- let generics = tcx.generics_of(def_id);
- let needs_inline = (generics.requires_monomorphization(tcx)
- || tcx.codegen_fn_attrs(def_id).requests_inline())
- && tcx.sess.opts.output_types.should_codegen();
- let always_encode_mir = tcx.sess.opts.debugging_opts.always_encode_mir;
- (false, needs_inline || always_encode_mir)
- }
- // Generators require optimized MIR to compute layout.
- DefKind::Generator => (false, true),
- // The others don't have MIR.
- _ => (false, false),
- }
-}
-
impl EncodeContext<'a, 'tcx> {
fn encode_def_ids(&mut self) {
if self.is_proc_macro {
@@ -930,6 +882,11 @@ impl EncodeContext<'a, 'tcx> {
self.encode_generics(def_id);
self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
+ let opt_mir = tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir;
+ if opt_mir {
+ self.encode_optimized_mir(def_id.expect_local());
+ }
+ self.encode_mir_for_ctfe(def_id.expect_local());
}
fn encode_info_for_mod(&mut self, id: hir::HirId, md: &hir::Mod<'_>) {
@@ -1015,6 +972,11 @@ impl EncodeContext<'a, 'tcx> {
self.encode_generics(def_id);
self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
+ let opt_mir = tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir;
+ if opt_mir {
+ self.encode_optimized_mir(def_id.expect_local());
+ }
+ self.encode_mir_for_ctfe(def_id.expect_local());
}
fn encode_generics(&mut self, def_id: DefId) {
@@ -1120,6 +1082,34 @@ impl EncodeContext<'a, 'tcx> {
self.encode_generics(def_id);
self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
+
+ // This should be kept in sync with `PrefetchVisitor.visit_trait_item`.
+ match trait_item.kind {
+ ty::AssocKind::Type => {}
+ ty::AssocKind::Const => {
+ if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) {
+ self.encode_mir_for_ctfe(def_id.expect_local());
+ self.encode_promoted_mir(def_id.expect_local());
+ }
+ }
+ ty::AssocKind::Fn => {
+ let opt_mir =
+ tcx.sess.opts.debugging_opts.always_encode_mir || self.emit_codegen_mir;
+ if opt_mir {
+ if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id.expect_local()) {
+ self.encode_optimized_mir(def_id.expect_local());
+ self.encode_promoted_mir(def_id.expect_local());
+ }
+ }
+ }
+ }
+ }
+
+ fn should_encode_fn_opt_mir(&self, def_id: DefId) -> bool {
+ self.tcx.sess.opts.debugging_opts.always_encode_mir
+ || (self.emit_codegen_mir
+ && (self.tcx.generics_of(def_id).requires_monomorphization(self.tcx)
+ || self.tcx.codegen_fn_attrs(def_id).requests_inline()))
}
fn encode_info_for_impl_item(&mut self, def_id: DefId) {
@@ -1181,6 +1171,27 @@ impl EncodeContext<'a, 'tcx> {
self.encode_generics(def_id);
self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
+
+ // The following part should be kept in sync with `PrefetchVisitor.visit_impl_item`.
+
+ let (mir, mir_const) = match ast_item.kind {
+ hir::ImplItemKind::Const(..) => (false, true),
+ hir::ImplItemKind::Fn(ref sig, _) => {
+ let opt_mir = self.should_encode_fn_opt_mir(def_id);
+ let is_const_fn = sig.header.constness == hir::Constness::Const;
+ (opt_mir, is_const_fn)
+ }
+ hir::ImplItemKind::TyAlias(..) => (false, false),
+ };
+ if mir {
+ self.encode_optimized_mir(def_id.expect_local());
+ }
+ if mir || mir_const {
+ self.encode_promoted_mir(def_id.expect_local());
+ }
+ if mir_const {
+ self.encode_mir_for_ctfe(def_id.expect_local());
+ }
}
fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) -> Lazy<[Ident]> {
@@ -1191,50 +1202,36 @@ impl EncodeContext<'a, 'tcx> {
self.lazy(param_names.iter())
}
- fn encode_mir(&mut self) {
- if self.is_proc_macro {
- return;
- }
+ fn encode_mir_for_ctfe(&mut self, def_id: LocalDefId) {
+ debug!("EntryBuilder::encode_mir_for_ctfe({:?})", def_id);
+ record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id));
- let mut keys_and_jobs = self
- .tcx
- .mir_keys(LOCAL_CRATE)
- .iter()
- .filter_map(|&def_id| {
- let (encode_const, encode_opt) = should_encode_mir(self.tcx, def_id);
- if encode_const || encode_opt {
- Some((def_id, encode_const, encode_opt))
- } else {
- None
- }
- })
- .collect::>();
- // Sort everything to ensure a stable order for diagnotics.
- keys_and_jobs.sort_by_key(|&(def_id, _, _)| def_id);
- for (def_id, encode_const, encode_opt) in keys_and_jobs.into_iter() {
- debug_assert!(encode_const || encode_opt);
+ let unused = self.tcx.unused_generic_params(def_id);
+ if !unused.is_empty() {
+ record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
+ }
- debug!("EntryBuilder::encode_mir({:?})", def_id);
- if encode_opt {
- record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
- }
- if encode_const {
- record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id));
+ let abstract_const = self.tcx.mir_abstract_const(def_id);
+ if let Ok(Some(abstract_const)) = abstract_const {
+ record!(self.tables.mir_abstract_consts[def_id.to_def_id()] <- abstract_const);
+ }
+ }
- let abstract_const = self.tcx.mir_abstract_const(def_id);
- if let Ok(Some(abstract_const)) = abstract_const {
- record!(self.tables.mir_abstract_consts[def_id.to_def_id()] <- abstract_const);
- }
- }
- record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id));
+ fn encode_optimized_mir(&mut self, def_id: LocalDefId) {
+ debug!("EntryBuilder::encode_optimized_mir({:?})", def_id);
+ record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
- let unused = self.tcx.unused_generic_params(def_id);
- if !unused.is_empty() {
- record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
- }
+ let unused = self.tcx.unused_generic_params(def_id);
+ if !unused.is_empty() {
+ record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
}
}
+ fn encode_promoted_mir(&mut self, def_id: LocalDefId) {
+ debug!("EncodeContext::encode_promoted_mir({:?})", def_id);
+ record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id));
+ }
+
// Encodes the inherent implementations of a structure, enumeration, or trait.
fn encode_inherent_implementations(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_inherent_implementations({:?})", def_id);
@@ -1490,6 +1487,28 @@ impl EncodeContext<'a, 'tcx> {
}
_ => {}
}
+
+ // The following part should be kept in sync with `PrefetchVisitor.visit_item`.
+
+ let (mir, const_mir) = match item.kind {
+ hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => (false, true),
+ hir::ItemKind::Fn(ref sig, ..) => {
+ let opt_mir = self.should_encode_fn_opt_mir(def_id);
+ let is_const_fn = sig.header.constness == hir::Constness::Const;
+ // We don't need the optimized MIR for const fns.
+ (opt_mir, is_const_fn)
+ }
+ _ => (false, false),
+ };
+ if mir {
+ self.encode_optimized_mir(def_id.expect_local());
+ }
+ if mir || const_mir {
+ self.encode_promoted_mir(def_id.expect_local());
+ }
+ if const_mir {
+ self.encode_mir_for_ctfe(def_id.expect_local());
+ }
}
/// Serialize the text of exported macros
@@ -1531,6 +1550,14 @@ impl EncodeContext<'a, 'tcx> {
record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig());
}
self.encode_generics(def_id.to_def_id());
+ let opt_mir = // FIXME: Optimized MIR is necessary to determine the layout of generators.
+ matches!(ty.kind(), ty::Generator(..))
+ || self.tcx.sess.opts.debugging_opts.always_encode_mir
+ || self.emit_codegen_mir;
+ if opt_mir {
+ self.encode_optimized_mir(def_id);
+ self.encode_promoted_mir(def_id);
+ }
}
fn encode_info_for_anon_const(&mut self, def_id: LocalDefId) {
@@ -1545,6 +1572,8 @@ impl EncodeContext<'a, 'tcx> {
self.encode_generics(def_id.to_def_id());
self.encode_explicit_predicates(def_id.to_def_id());
self.encode_inferred_outlives(def_id.to_def_id());
+ self.encode_mir_for_ctfe(def_id);
+ self.encode_promoted_mir(def_id);
}
fn encode_native_libraries(&mut self) -> Lazy<[NativeLib]> {
@@ -2009,25 +2038,90 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
/// Used to prefetch queries which will be needed later by metadata encoding.
/// Only a subset of the queries are actually prefetched to keep this code smaller.
-fn prefetch_mir(tcx: TyCtxt<'_>) {
- if !tcx.sess.opts.output_types.should_codegen() {
- // We won't emit MIR, so don't prefetch it.
- return;
- }
+struct PrefetchVisitor<'tcx> {
+ tcx: TyCtxt<'tcx>,
+ mir_keys: &'tcx FxHashSet,
+}
- par_iter(tcx.mir_keys(LOCAL_CRATE)).for_each(|&def_id| {
- let (encode_const, encode_opt) = should_encode_mir(tcx, def_id);
+impl<'tcx> PrefetchVisitor<'tcx> {
+ fn prefetch_ctfe_mir(&self, def_id: LocalDefId) {
+ if self.mir_keys.contains(&def_id) {
+ self.tcx.ensure().mir_for_ctfe(def_id);
+ self.tcx.ensure().promoted_mir(def_id);
+ }
+ }
+ fn prefetch_mir(&self, def_id: LocalDefId) {
+ if self.mir_keys.contains(&def_id) {
+ self.tcx.ensure().optimized_mir(def_id);
+ self.tcx.ensure().promoted_mir(def_id);
+ }
+ }
+}
- if encode_const {
- tcx.ensure().mir_for_ctfe(def_id);
+impl<'tcx, 'v> ParItemLikeVisitor<'v> for PrefetchVisitor<'tcx> {
+ fn visit_item(&self, item: &hir::Item<'_>) {
+ // This should be kept in sync with `encode_info_for_item`.
+ let tcx = self.tcx;
+ match item.kind {
+ hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => {
+ self.prefetch_ctfe_mir(tcx.hir().local_def_id(item.hir_id))
+ }
+ hir::ItemKind::Fn(ref sig, ..) => {
+ let def_id = tcx.hir().local_def_id(item.hir_id);
+ let opt_mir = tcx.generics_of(def_id.to_def_id()).requires_monomorphization(tcx)
+ || tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline();
+ if opt_mir {
+ self.prefetch_mir(def_id)
+ }
+ if sig.header.constness == hir::Constness::Const {
+ self.prefetch_ctfe_mir(def_id);
+ }
+ }
+ _ => (),
}
- if encode_opt {
- tcx.ensure().optimized_mir(def_id);
+ }
+
+ fn visit_trait_item(&self, trait_item: &'v hir::TraitItem<'v>) {
+ // This should be kept in sync with `encode_info_for_trait_item`.
+ let def_id = self.tcx.hir().local_def_id(trait_item.hir_id);
+ match trait_item.kind {
+ hir::TraitItemKind::Type(..) => {}
+ hir::TraitItemKind::Const(..) => {
+ self.prefetch_ctfe_mir(def_id);
+ }
+ hir::TraitItemKind::Fn(..) => {
+ self.prefetch_mir(def_id);
+ }
}
- if encode_opt || encode_const {
- tcx.ensure().promoted_mir(def_id);
+ }
+
+ fn visit_impl_item(&self, impl_item: &'v hir::ImplItem<'v>) {
+ // This should be kept in sync with `encode_info_for_impl_item`.
+ let tcx = self.tcx;
+ match impl_item.kind {
+ hir::ImplItemKind::Const(..) => {
+ self.prefetch_ctfe_mir(tcx.hir().local_def_id(impl_item.hir_id))
+ }
+ hir::ImplItemKind::Fn(ref sig, _) => {
+ let def_id = tcx.hir().local_def_id(impl_item.hir_id);
+ let opt_mir = tcx.generics_of(def_id.to_def_id()).requires_monomorphization(tcx)
+ || tcx.codegen_fn_attrs(def_id.to_def_id()).requests_inline();
+ let is_const_fn = sig.header.constness == hir::Constness::Const;
+ if opt_mir {
+ self.prefetch_mir(def_id)
+ }
+ if is_const_fn {
+ self.prefetch_ctfe_mir(def_id);
+ }
+ }
+ hir::ImplItemKind::TyAlias(..) => (),
}
- })
+ }
+
+ fn visit_foreign_item(&self, _foreign_item: &'v hir::ForeignItem<'v>) {
+ // This should be kept in sync with `encode_info_for_foreign_item`.
+ // Foreign items contain no MIR.
+ }
}
// NOTE(eddyb) The following comment was preserved for posterity, even
@@ -2067,7 +2161,19 @@ pub(super) fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
// Prefetch some queries used by metadata encoding.
// This is not necessary for correctness, but is only done for performance reasons.
// It can be removed if it turns out to cause trouble or be detrimental to performance.
- join(|| prefetch_mir(tcx), || tcx.exported_symbols(LOCAL_CRATE));
+ join(
+ || {
+ if !tcx.sess.opts.output_types.should_codegen() {
+ // We won't emit MIR, so don't prefetch it.
+ return;
+ }
+ tcx.hir().krate().par_visit_all_item_likes(&PrefetchVisitor {
+ tcx,
+ mir_keys: tcx.mir_keys(LOCAL_CRATE),
+ });
+ },
+ || tcx.exported_symbols(LOCAL_CRATE),
+ );
},
)
.0
@@ -2100,6 +2206,7 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
required_source_files,
is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro),
hygiene_ctxt: &hygiene_ctxt,
+ emit_codegen_mir: tcx.sess.opts.output_types.should_codegen(),
};
// Encode the rustc version string in a predictable location.
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index d33aad3b71040..47b7768b410a1 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -26,7 +26,7 @@ rustc_index = { path = "../rustc_index" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_ast = { path = "../rustc_ast" }
rustc_span = { path = "../rustc_span" }
-chalk-ir = "0.55.0"
+chalk-ir = "0.36.0"
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
measureme = "9.0.0"
rustc_session = { path = "../rustc_session" }
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index ee12c0e786d41..412d5b5082be3 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -569,9 +569,9 @@ impl<'hir> Map<'hir> {
self.find(self.get_parent_node(id)),
Some(
Node::Item(_)
- | Node::TraitItem(_)
- | Node::ImplItem(_)
- | Node::Expr(Expr { kind: ExprKind::Closure(..), .. }),
+ | Node::TraitItem(_)
+ | Node::ImplItem(_)
+ | Node::Expr(Expr { kind: ExprKind::Closure(..), .. }),
)
)
}
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index ca73481b21699..0bdccf7b5f073 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -5,10 +5,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_hir::HirId;
-use rustc_session::lint::{
- builtin::{self, FORBIDDEN_LINT_GROUPS},
- Level, Lint, LintId,
-};
+use rustc_session::lint::{builtin, Level, Lint, LintId};
use rustc_session::{DiagnosticMessageId, Session};
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan};
@@ -92,12 +89,7 @@ impl LintLevelSets {
// If we're about to issue a warning, check at the last minute for any
// directives against the warnings "lint". If, for example, there's an
// `allow(warnings)` in scope then we want to respect that instead.
- //
- // We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically
- // triggers in cases (like #80988) where you have `forbid(warnings)`,
- // and so if we turned that into an error, it'd defeat the purpose of the
- // future compatibility warning.
- if level == Level::Warn && LintId::of(lint) != LintId::of(FORBIDDEN_LINT_GROUPS) {
+ if level == Level::Warn {
let (warnings_level, warnings_src) =
self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux);
if let Some(configured_warning_level) = warnings_level {
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 4bb39fe4a527e..f288ad8d1d4a3 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -96,7 +96,7 @@ impl<'tcx> ConstValue<'tcx> {
}
/// A `Scalar` represents an immediate, primitive value existing outside of a
-/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 16 bytes in
+/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
/// size. Like a range of bytes in an `Allocation`, a `Scalar` can either represent the raw bytes
/// of a simple value or a pointer into another `Allocation`
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, TyEncodable, TyDecodable, Hash)]
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 718e81c84eddd..cd2bea86ea1a7 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -962,7 +962,8 @@ impl<'tcx> LocalDecl<'tcx> {
opt_ty_info: _,
opt_match_place: _,
pat_span: _,
- }) | BindingForm::ImplicitSelf(ImplicitSelfKind::Imm),
+ })
+ | BindingForm::ImplicitSelf(ImplicitSelfKind::Imm),
)))
)
}
@@ -979,7 +980,8 @@ impl<'tcx> LocalDecl<'tcx> {
opt_ty_info: _,
opt_match_place: _,
pat_span: _,
- }) | BindingForm::ImplicitSelf(_),
+ })
+ | BindingForm::ImplicitSelf(_),
)))
)
}
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index f0166ec21672b..d89e3ab4352bb 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -13,6 +13,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
use rustc_query_system::query::QueryDescription;
use rustc_span::symbol::Symbol;
+use std::borrow::Cow;
fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
if def_id.is_top_level_module() {
@@ -34,1602 +35,1684 @@ fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
// Queries marked with `fatal_cycle` do not need the latter implementation,
// as they will raise an fatal error on query cycles instead.
rustc_queries! {
- query trigger_delay_span_bug(key: DefId) -> () {
- desc { "trigger a delay span bug" }
+ Other {
+ query trigger_delay_span_bug(key: DefId) -> () {
+ desc { "trigger a delay span bug" }
+ }
}
- /// Represents crate as a whole (as distinct from the top-level crate module).
- /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
- /// we will have to assume that any change means that you need to be recompiled.
- /// This is because the `hir_crate` query gives you access to all other items.
- /// To avoid this fate, do not call `tcx.hir().krate()`; instead,
- /// prefer wrappers like `tcx.visit_all_items_in_krate()`.
- query hir_crate(key: CrateNum) -> &'tcx Crate<'tcx> {
- eval_always
- no_hash
- desc { "get the crate HIR" }
- }
+ Other {
+ /// Represents crate as a whole (as distinct from the top-level crate module).
+ /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`),
+ /// we will have to assume that any change means that you need to be recompiled.
+ /// This is because the `hir_crate` query gives you access to all other items.
+ /// To avoid this fate, do not call `tcx.hir().krate()`; instead,
+ /// prefer wrappers like `tcx.visit_all_items_in_krate()`.
+ query hir_crate(key: CrateNum) -> &'tcx Crate<'tcx> {
+ eval_always
+ no_hash
+ desc { "get the crate HIR" }
+ }
- /// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
- /// Avoid calling this query directly.
- query index_hir(_: CrateNum) -> &'tcx map::IndexedHir<'tcx> {
- eval_always
- no_hash
- desc { "index HIR" }
- }
+ /// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
+ /// Avoid calling this query directly.
+ query index_hir(_: CrateNum) -> &'tcx map::IndexedHir<'tcx> {
+ eval_always
+ no_hash
+ desc { "index HIR" }
+ }
- /// The items in a module.
- ///
- /// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
- /// Avoid calling this query directly.
- query hir_module_items(key: LocalDefId) -> &'tcx hir::ModuleItems {
- eval_always
- desc { |tcx| "HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
- }
+ /// The items in a module.
+ ///
+ /// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
+ /// Avoid calling this query directly.
+ query hir_module_items(key: LocalDefId) -> &'tcx hir::ModuleItems {
+ eval_always
+ desc { |tcx| "HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) }
+ }
- /// Gives access to the HIR node for the HIR owner `key`.
- ///
- /// This can be conveniently accessed by methods on `tcx.hir()`.
- /// Avoid calling this query directly.
- query hir_owner(key: LocalDefId) -> Option<&'tcx crate::hir::Owner<'tcx>> {
- eval_always
- desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
- }
+ /// Gives access to the HIR node for the HIR owner `key`.
+ ///
+ /// This can be conveniently accessed by methods on `tcx.hir()`.
+ /// Avoid calling this query directly.
+ query hir_owner(key: LocalDefId) -> Option<&'tcx crate::hir::Owner<'tcx>> {
+ eval_always
+ desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
+ }
- /// Gives access to the HIR nodes and bodies inside the HIR owner `key`.
- ///
- /// This can be conveniently accessed by methods on `tcx.hir()`.
- /// Avoid calling this query directly.
- query hir_owner_nodes(key: LocalDefId) -> Option<&'tcx crate::hir::OwnerNodes<'tcx>> {
- eval_always
- desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
- }
+ /// Gives access to the HIR nodes and bodies inside the HIR owner `key`.
+ ///
+ /// This can be conveniently accessed by methods on `tcx.hir()`.
+ /// Avoid calling this query directly.
+ query hir_owner_nodes(key: LocalDefId) -> Option<&'tcx crate::hir::OwnerNodes<'tcx>> {
+ eval_always
+ desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
+ }
- /// Computes the `DefId` of the corresponding const parameter in case the `key` is a
- /// const argument and returns `None` otherwise.
- ///
- /// ```ignore (incomplete)
- /// let a = foo::<7>();
- /// // ^ Calling `opt_const_param_of` for this argument,
- ///
- /// fn foo()
- /// // ^ returns this `DefId`.
- ///
- /// fn bar() {
- /// // ^ While calling `opt_const_param_of` for other bodies returns `None`.
- /// }
- /// ```
- // It looks like caching this query on disk actually slightly
- // worsened performance in #74376.
- //
- // Once const generics are more prevalently used, we might want to
- // consider only caching calls returning `Some`.
- query opt_const_param_of(key: LocalDefId) -> Option {
- desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) }
- }
+ /// Computes the `DefId` of the corresponding const parameter in case the `key` is a
+ /// const argument and returns `None` otherwise.
+ ///
+ /// ```ignore (incomplete)
+ /// let a = foo::<7>();
+ /// // ^ Calling `opt_const_param_of` for this argument,
+ ///
+ /// fn foo()
+ /// // ^ returns this `DefId`.
+ ///
+ /// fn bar() {
+ /// // ^ While calling `opt_const_param_of` for other bodies returns `None`.
+ /// }
+ /// ```
+ // It looks like caching this query on disk actually slightly
+ // worsened performance in #74376.
+ //
+ // Once const generics are more prevalently used, we might want to
+ // consider only caching calls returning `Some`.
+ query opt_const_param_of(key: LocalDefId) -> Option {
+ desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) }
+ }
- /// Records the type of every item.
- query type_of(key: DefId) -> Ty<'tcx> {
- desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) }
- cache_on_disk_if { key.is_local() }
- }
+ /// Records the type of every item.
+ query type_of(key: DefId) -> Ty<'tcx> {
+ desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) }
+ cache_on_disk_if { key.is_local() }
+ }
- query analysis(key: CrateNum) -> Result<(), ErrorReported> {
- eval_always
- desc { "running analysis passes on this crate" }
- }
+ query analysis(key: CrateNum) -> Result<(), ErrorReported> {
+ eval_always
+ desc { "running analysis passes on this crate" }
+ }
- /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its
- /// associated generics.
- query generics_of(key: DefId) -> ty::Generics {
- desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) }
- storage(ArenaCacheSelector<'tcx>)
- cache_on_disk_if { key.is_local() }
- load_cached(tcx, id) {
- let generics: Option = tcx.queries.on_disk_cache.as_ref()
- .and_then(|c| c.try_load_query_result(tcx, id));
- generics
+ /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its
+ /// associated generics.
+ query generics_of(key: DefId) -> ty::Generics {
+ desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) }
+ storage(ArenaCacheSelector<'tcx>)
+ cache_on_disk_if { key.is_local() }
+ load_cached(tcx, id) {
+ let generics: Option = tcx.queries.on_disk_cache.as_ref()
+ .and_then(|c| c.try_load_query_result(tcx, id));
+ generics
+ }
}
- }
- /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
- /// predicates (where-clauses) that must be proven true in order
- /// to reference it. This is almost always the "predicates query"
- /// that you want.
- ///
- /// `predicates_of` builds on `predicates_defined_on` -- in fact,
- /// it is almost always the same as that query, except for the
- /// case of traits. For traits, `predicates_of` contains
- /// an additional `Self: Trait<...>` predicate that users don't
- /// actually write. This reflects the fact that to invoke the
- /// trait (e.g., via `Default::default`) you must supply types
- /// that actually implement the trait. (However, this extra
- /// predicate gets in the way of some checks, which are intended
- /// to operate over only the actual where-clauses written by the
- /// user.)
- query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
- desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) }
- cache_on_disk_if { key.is_local() }
- }
+ /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
+ /// predicates (where-clauses) that must be proven true in order
+ /// to reference it. This is almost always the "predicates query"
+ /// that you want.
+ ///
+ /// `predicates_of` builds on `predicates_defined_on` -- in fact,
+ /// it is almost always the same as that query, except for the
+ /// case of traits. For traits, `predicates_of` contains
+ /// an additional `Self: Trait<...>` predicate that users don't
+ /// actually write. This reflects the fact that to invoke the
+ /// trait (e.g., via `Default::default`) you must supply types
+ /// that actually implement the trait. (However, this extra
+ /// predicate gets in the way of some checks, which are intended
+ /// to operate over only the actual where-clauses written by the
+ /// user.)
+ query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
+ desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) }
+ cache_on_disk_if { key.is_local() }
+ }
- /// Returns the list of bounds that can be used for
- /// `SelectionCandidate::ProjectionCandidate(_)` and
- /// `ProjectionTyCandidate::TraitDef`.
- /// Specifically this is the bounds written on the trait's type
- /// definition, or those after the `impl` keyword
- ///
- /// ```ignore (incomplete)
- /// type X: Bound + 'lt
- /// // ^^^^^^^^^^^
- /// impl Debug + Display
- /// // ^^^^^^^^^^^^^^^
- /// ```
- ///
- /// `key` is the `DefId` of the associated type or opaque type.
- ///
- /// Bounds from the parent (e.g. with nested impl trait) are not included.
- query explicit_item_bounds(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
- desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
- }
+ /// Returns the list of bounds that can be used for
+ /// `SelectionCandidate::ProjectionCandidate(_)` and
+ /// `ProjectionTyCandidate::TraitDef`.
+ /// Specifically this is the bounds written on the trait's type
+ /// definition, or those after the `impl` keyword
+ ///
+ /// ```ignore (incomplete)
+ /// type X: Bound + 'lt
+ /// // ^^^^^^^^^^^
+ /// impl Debug + Display
+ /// // ^^^^^^^^^^^^^^^
+ /// ```
+ ///
+ /// `key` is the `DefId` of the associated type or opaque type.
+ ///
+ /// Bounds from the parent (e.g. with nested impl trait) are not included.
+ query explicit_item_bounds(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
+ desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) }
+ }
- /// Elaborated version of the predicates from `explicit_item_bounds`.
- ///
- /// For example:
- ///
- /// ```
- /// trait MyTrait {
- /// type MyAType: Eq + ?Sized;
- /// }
- /// ```
- ///
- /// `explicit_item_bounds` returns `[::MyAType: Eq]`,
- /// and `item_bounds` returns
- /// ```text
- /// [
- /// ::MyAType: Eq,
- /// ::MyAType: PartialEq<::MyAType>
- /// ]
- /// ```
- ///
- /// Bounds from the parent (e.g. with nested impl trait) are not included.
- query item_bounds(key: DefId) -> &'tcx ty::List> {
- desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
- }
+ /// Elaborated version of the predicates from `explicit_item_bounds`.
+ ///
+ /// For example:
+ ///
+ /// ```
+ /// trait MyTrait {
+ /// type MyAType: Eq + ?Sized;
+ /// }
+ /// ```
+ ///
+ /// `explicit_item_bounds` returns `[::MyAType: Eq]`,
+ /// and `item_bounds` returns
+ /// ```text
+ /// [
+ /// ::MyAType: Eq,
+ /// ::MyAType: PartialEq<::MyAType>
+ /// ]
+ /// ```
+ ///
+ /// Bounds from the parent (e.g. with nested impl trait) are not included.
+ query item_bounds(key: DefId) -> &'tcx ty::List> {
+ desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
+ }
- query projection_ty_from_predicates(key: (DefId, DefId)) -> Option> {
- desc { |tcx| "finding projection type inside predicates of `{}`", tcx.def_path_str(key.0) }
- }
+ query projection_ty_from_predicates(key: (DefId, DefId)) -> Option> {
+ desc { |tcx| "finding projection type inside predicates of `{}`", tcx.def_path_str(key.0) }
+ }
- query native_libraries(_: CrateNum) -> Lrc> {
- desc { "looking up the native libraries of a linked crate" }
- }
+ query native_libraries(_: CrateNum) -> Lrc> {
+ desc { "looking up the native libraries of a linked crate" }
+ }
- query lint_levels(_: CrateNum) -> LintLevelMap {
- storage(ArenaCacheSelector<'tcx>)
- eval_always
- desc { "computing the lint levels for items in this crate" }
- }
+ query lint_levels(_: CrateNum) -> LintLevelMap {
+ storage(ArenaCacheSelector<'tcx>)
+ eval_always
+ desc { "computing the lint levels for items in this crate" }
+ }
- query parent_module_from_def_id(key: LocalDefId) -> LocalDefId {
- eval_always
- desc { |tcx| "parent module of `{}`", tcx.def_path_str(key.to_def_id()) }
- }
+ query parent_module_from_def_id(key: LocalDefId) -> LocalDefId {
+ eval_always
+ desc { |tcx| "parent module of `{}`", tcx.def_path_str(key.to_def_id()) }
+ }
- /// Internal helper query. Use `tcx.expansion_that_defined` instead
- query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
- desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
+ /// Internal helper query. Use `tcx.expansion_that_defined` instead
+ query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
+ desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
+ }
}
- query is_panic_runtime(_: CrateNum) -> bool {
- fatal_cycle
- desc { "checking if the crate is_panic_runtime" }
+ Codegen {
+ query is_panic_runtime(_: CrateNum) -> bool {
+ fatal_cycle
+ desc { "checking if the crate is_panic_runtime" }
+ }
}
- /// Set of all the `DefId`s in this crate that have MIR associated with
- /// them. This includes all the body owners, but also things like struct
- /// constructors.
- query mir_keys(_: CrateNum) -> FxHashSet {
- storage(ArenaCacheSelector<'tcx>)
- desc { "getting a list of all mir_keys" }
- }
+ Codegen {
+ /// Set of all the `DefId`s in this crate that have MIR associated with
+ /// them. This includes all the body owners, but also things like struct
+ /// constructors.
+ query mir_keys(_: CrateNum) -> FxHashSet {
+ storage(ArenaCacheSelector<'tcx>)
+ desc { "getting a list of all mir_keys" }
+ }
- /// Maps DefId's that have an associated `mir::Body` to the result
- /// of the MIR const-checking pass. This is the set of qualifs in
- /// the final value of a `const`.
- query mir_const_qualif(key: DefId) -> mir::ConstQualifs {
- desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
- cache_on_disk_if { key.is_local() }
- }
- query mir_const_qualif_const_arg(
- key: (LocalDefId, DefId)
- ) -> mir::ConstQualifs {
- desc {
- |tcx| "const checking the const argument `{}`",
- tcx.def_path_str(key.0.to_def_id())
+ /// Maps DefId's that have an associated `mir::Body` to the result
+ /// of the MIR const-checking pass. This is the set of qualifs in
+ /// the final value of a `const`.
+ query mir_const_qualif(key: DefId) -> mir::ConstQualifs {
+ desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
+ cache_on_disk_if { key.is_local() }
+ }
+ query mir_const_qualif_const_arg(
+ key: (LocalDefId, DefId)
+ ) -> mir::ConstQualifs {
+ desc {
+ |tcx| "const checking the const argument `{}`",
+ tcx.def_path_str(key.0.to_def_id())
+ }
}
- }
- /// Fetch the MIR for a given `DefId` right after it's built - this includes
- /// unreachable code.
- query mir_built(key: ty::WithOptConstParam) -> &'tcx Steal> {
- desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
- }
+ /// Fetch the MIR for a given `DefId` right after it's built - this includes
+ /// unreachable code.
+ query mir_built(key: ty::WithOptConstParam) -> &'tcx Steal> {
+ desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
+ }
- /// Fetch the MIR for a given `DefId` up till the point where it is
- /// ready for const qualification.
- ///
- /// See the README for the `mir` module for details.
- query mir_const(key: ty::WithOptConstParam) -> &'tcx Steal> {
- desc {
- |tcx| "processing MIR for {}`{}`",
- if key.const_param_did.is_some() { "the const argument " } else { "" },
- tcx.def_path_str(key.did.to_def_id()),
- }
- no_hash
- }
+ /// Fetch the MIR for a given `DefId` up till the point where it is
+ /// ready for const qualification.
+ ///
+ /// See the README for the `mir` module for details.
+ query mir_const(key: ty::WithOptConstParam) -> &'tcx Steal> {
+ desc {
+ |tcx| "processing MIR for {}`{}`",
+ if key.const_param_did.is_some() { "the const argument " } else { "" },
+ tcx.def_path_str(key.did.to_def_id()),
+ }
+ no_hash
+ }
- /// Try to build an abstract representation of the given constant.
- query mir_abstract_const(
- key: DefId
- ) -> Result