summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_ast_passes
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast_passes')
-rw-r--r--compiler/rustc_ast_passes/messages.ftl (renamed from compiler/rustc_ast_passes/locales/en-US.ftl)7
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs79
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs14
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs92
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs3
5 files changed, 105 insertions, 90 deletions
diff --git a/compiler/rustc_ast_passes/locales/en-US.ftl b/compiler/rustc_ast_passes/messages.ftl
index 747bd52b2..a349fe6a3 100644
--- a/compiler/rustc_ast_passes/locales/en-US.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -17,9 +17,10 @@ ast_passes_keyword_lifetime =
ast_passes_invalid_label =
invalid label name `{$name}`
-ast_passes_invalid_visibility =
- unnecessary visibility qualifier
- .implied = `pub` not permitted here because it's implied
+ast_passes_visibility_not_permitted =
+ visibility qualifiers are not permitted here
+ .enum_variant = enum variants and their fields always share the visibility of the enum they are in
+ .trait_impl = trait items always share the visibility of their trait
.individual_impl_items = place qualifiers on individual impl items instead
.individual_foreign_items = place qualifiers on individual foreign items instead
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 2cc009410..c79626ccd 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -9,10 +9,10 @@
use itertools::{Either, Itertools};
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
-use rustc_ast::walk_list;
use rustc_ast::*;
+use rustc_ast::{walk_list, StaticItem};
use rustc_ast_pretty::pprust::{self, State};
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
use rustc_macros::Subdiagnostic;
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::{
@@ -240,16 +240,12 @@ impl<'a> AstValidator<'a> {
}
}
- fn invalid_visibility(&self, vis: &Visibility, note: Option<errors::InvalidVisibilityNote>) {
+ fn visibility_not_permitted(&self, vis: &Visibility, note: errors::VisibilityNotPermittedNote) {
if let VisibilityKind::Inherited = vis.kind {
return;
}
- self.session.emit_err(errors::InvalidVisibility {
- span: vis.span,
- implied: vis.kind.is_pub().then_some(vis.span),
- note,
- });
+ self.session.emit_err(errors::VisibilityNotPermitted { span: vis.span, note });
}
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
@@ -643,7 +639,7 @@ fn validate_generic_param_order(
span: Span,
) {
let mut max_param: Option<ParamKindOrd> = None;
- let mut out_of_order = FxHashMap::default();
+ let mut out_of_order = FxIndexMap::default();
let mut param_idents = Vec::with_capacity(generics.len());
for (idx, param) in generics.iter().enumerate() {
@@ -691,7 +687,7 @@ fn validate_generic_param_order(
GenericParamKind::Lifetime => (),
GenericParamKind::Const { ty: _, kw_span: _, default: Some(default) } => {
ordered_params += " = ";
- ordered_params += &pprust::expr_to_string(&*default.value);
+ ordered_params += &pprust::expr_to_string(&default.value);
}
GenericParamKind::Const { ty: _, kw_span: _, default: None } => (),
}
@@ -799,11 +795,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
fn visit_item(&mut self, item: &'a Item) {
- if item.attrs.iter().any(|attr| self.session.is_proc_macro_attr(attr)) {
+ if item.attrs.iter().any(|attr| attr.is_proc_macro_attr()) {
self.has_proc_macro_decls = true;
}
- if self.session.contains_name(&item.attrs, sym::no_mangle) {
+ if attr::contains_name(&item.attrs, sym::no_mangle) {
self.check_nomangle_item_asciionly(item.ident, item.span);
}
@@ -819,7 +815,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
items,
}) => {
self.with_in_trait_impl(true, Some(*constness), |this| {
- this.invalid_visibility(&item.vis, None);
+ this.visibility_not_permitted(
+ &item.vis,
+ errors::VisibilityNotPermittedNote::TraitImpl,
+ );
if let TyKind::Err = self_ty.kind {
this.err_handler().emit_err(errors::ObsoleteAuto { span: item.span });
}
@@ -866,9 +865,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
only_trait: only_trait.then_some(()),
};
- self.invalid_visibility(
+ self.visibility_not_permitted(
&item.vis,
- Some(errors::InvalidVisibilityNote::IndividualImplItems),
+ errors::VisibilityNotPermittedNote::IndividualImplItems,
);
if let &Unsafe::Yes(span) = unsafety {
self.err_handler().emit_err(errors::InherentImplCannotUnsafe {
@@ -924,9 +923,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
ItemKind::ForeignMod(ForeignMod { abi, unsafety, .. }) => {
let old_item = mem::replace(&mut self.extern_mod, Some(item));
- self.invalid_visibility(
+ self.visibility_not_permitted(
&item.vis,
- Some(errors::InvalidVisibilityNote::IndividualForeignItems),
+ errors::VisibilityNotPermittedNote::IndividualForeignItems,
);
if let &Unsafe::Yes(span) = unsafety {
self.err_handler().emit_err(errors::UnsafeItem { span, kind: "extern block" });
@@ -940,9 +939,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
ItemKind::Enum(def, _) => {
for variant in &def.variants {
- self.invalid_visibility(&variant.vis, None);
+ self.visibility_not_permitted(
+ &variant.vis,
+ errors::VisibilityNotPermittedNote::EnumVariant,
+ );
for field in variant.data.fields() {
- self.invalid_visibility(&field.vis, None);
+ self.visibility_not_permitted(
+ &field.vis,
+ errors::VisibilityNotPermittedNote::EnumVariant,
+ );
}
}
}
@@ -973,7 +978,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _))
- && !self.session.contains_name(&item.attrs, sym::path)
+ && !attr::contains_name(&item.attrs, sym::path)
{
self.check_mod_file_item_asciionly(item.ident);
}
@@ -983,14 +988,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.err_handler().emit_err(errors::FieldlessUnion { span: item.span });
}
}
- ItemKind::Const(def, .., None) => {
- self.check_defaultness(item.span, *def);
+ ItemKind::Const(box ConstItem { defaultness, expr: None, .. }) => {
+ self.check_defaultness(item.span, *defaultness);
self.session.emit_err(errors::ConstWithoutBody {
span: item.span,
replace_span: self.ending_semi_or_hi(item.span),
});
}
- ItemKind::Static(.., None) => {
+ ItemKind::Static(box StaticItem { expr: None, .. }) => {
self.session.emit_err(errors::StaticWithoutBody {
span: item.span,
replace_span: self.ending_semi_or_hi(item.span),
@@ -1248,7 +1253,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
- if self.session.contains_name(&item.attrs, sym::no_mangle) {
+ if attr::contains_name(&item.attrs, sym::no_mangle) {
self.check_nomangle_item_asciionly(item.ident, item.span);
}
@@ -1258,13 +1263,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if ctxt == AssocCtxt::Impl {
match &item.kind {
- AssocItemKind::Const(_, _, body) => {
- if body.is_none() {
- self.session.emit_err(errors::AssocConstWithoutBody {
- span: item.span,
- replace_span: self.ending_semi_or_hi(item.span),
- });
- }
+ AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
+ self.session.emit_err(errors::AssocConstWithoutBody {
+ span: item.span,
+ replace_span: self.ending_semi_or_hi(item.span),
+ });
}
AssocItemKind::Fn(box Fn { body, .. }) => {
if body.is_none() {
@@ -1302,7 +1305,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
- self.invalid_visibility(&item.vis, None);
+ self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
self.check_trait_fn_not_const(sig.header.constness);
}
@@ -1392,11 +1395,13 @@ fn deny_equality_constraints(
}
},
empty_args => {
- *empty_args = AngleBracketedArgs {
- span: ident.span,
- args: thin_vec![arg],
- }
- .into();
+ *empty_args = Some(
+ AngleBracketedArgs {
+ span: ident.span,
+ args: thin_vec![arg],
+ }
+ .into(),
+ );
}
}
err.assoc = Some(errors::AssociatedSuggestion {
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index d007097d9..27bbd2379 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -42,18 +42,20 @@ pub struct InvalidLabel {
}
#[derive(Diagnostic)]
-#[diag(ast_passes_invalid_visibility, code = "E0449")]
-pub struct InvalidVisibility {
+#[diag(ast_passes_visibility_not_permitted, code = "E0449")]
+pub struct VisibilityNotPermitted {
#[primary_span]
pub span: Span,
- #[label(ast_passes_implied)]
- pub implied: Option<Span>,
#[subdiagnostic]
- pub note: Option<InvalidVisibilityNote>,
+ pub note: VisibilityNotPermittedNote,
}
#[derive(Subdiagnostic)]
-pub enum InvalidVisibilityNote {
+pub enum VisibilityNotPermittedNote {
+ #[note(ast_passes_enum_variant)]
+ EnumVariant,
+ #[note(ast_passes_trait_impl)]
+ TraitImpl,
#[note(ast_passes_individual_impl_items)]
IndividualImplItems,
#[note(ast_passes_individual_foreign_items)]
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 96042ea30..17bcd24ee 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -1,6 +1,6 @@
use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
-use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
+use rustc_ast::{attr, AssocConstraint, AssocConstraintKind, NodeId};
use rustc_ast::{PatKind, RangeEnd};
use rustc_errors::{Applicability, StashKey};
use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
@@ -121,24 +121,34 @@ impl<'a> PostExpansionVisitor<'a> {
}
/// Feature gate `impl Trait` inside `type Alias = $type_expr;`.
- fn check_impl_trait(&self, ty: &ast::Ty) {
+ fn check_impl_trait(&self, ty: &ast::Ty, in_associated_ty: bool) {
struct ImplTraitVisitor<'a> {
vis: &'a PostExpansionVisitor<'a>,
+ in_associated_ty: bool,
}
impl Visitor<'_> for ImplTraitVisitor<'_> {
fn visit_ty(&mut self, ty: &ast::Ty) {
if let ast::TyKind::ImplTrait(..) = ty.kind {
- gate_feature_post!(
- &self.vis,
- type_alias_impl_trait,
- ty.span,
- "`impl Trait` in type aliases is unstable"
- );
+ if self.in_associated_ty {
+ gate_feature_post!(
+ &self.vis,
+ impl_trait_in_assoc_type,
+ ty.span,
+ "`impl Trait` in associated types is unstable"
+ );
+ } else {
+ gate_feature_post!(
+ &self.vis,
+ type_alias_impl_trait,
+ ty.span,
+ "`impl Trait` in type aliases is unstable"
+ );
+ }
}
visit::walk_ty(self, ty);
}
}
- ImplTraitVisitor { vis: self }.visit_ty(ty);
+ ImplTraitVisitor { vis: self, in_associated_ty }.visit_ty(ty);
}
fn check_late_bound_lifetime_defs(&self, params: &[ast::GenericParam]) {
@@ -232,7 +242,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
ast::ItemKind::Fn(..) => {
- if self.sess.contains_name(&i.attrs, sym::start) {
+ if attr::contains_name(&i.attrs, sym::start) {
gate_feature_post!(
&self,
start,
@@ -245,7 +255,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
ast::ItemKind::Struct(..) => {
- for attr in self.sess.filter_by_name(&i.attrs, sym::repr) {
+ for attr in attr::filter_by_name(&i.attrs, sym::repr) {
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
if item.has_name(sym::simd) {
gate_feature_post!(
@@ -294,7 +304,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}
ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => {
- self.check_impl_trait(&ty)
+ self.check_impl_trait(&ty, false)
}
_ => {}
@@ -306,7 +316,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
match i.kind {
ast::ForeignItemKind::Fn(..) | ast::ForeignItemKind::Static(..) => {
- let link_name = self.sess.first_attr_value_str_by_name(&i.attrs, sym::link_name);
+ let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
let links_to_llvm =
link_name.map_or(false, |val| val.as_str().starts_with("llvm."));
if links_to_llvm {
@@ -337,9 +347,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
ast::TyKind::Never => {
gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental");
}
- ast::TyKind::TraitObject(_, ast::TraitObjectSyntax::DynStar, ..) => {
- gate_feature_post!(&self, dyn_star, ty.span, "dyn* trait objects are unstable");
- }
_ => {}
}
visit::walk_ty(self, ty)
@@ -395,14 +402,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_expr(&mut self, e: &'a ast::Expr) {
match e.kind {
- ast::ExprKind::Box(_) => {
- gate_feature_post!(
- &self,
- box_syntax,
- e.span,
- "box expression syntax is experimental; you can call `Box::new` instead"
- );
- }
ast::ExprKind::Type(..) => {
if self.sess.parse_sess.span_diagnostic.err_count() == 0 {
// To avoid noise about type ascription in common syntax errors,
@@ -415,24 +414,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
);
} else {
// And if it isn't, cancel the early-pass warning.
- self.sess
+ if let Some(err) = self
+ .sess
.parse_sess
.span_diagnostic
.steal_diagnostic(e.span, StashKey::EarlySyntaxWarning)
- .map(|err| err.cancel());
+ {
+ err.cancel()
+ }
}
}
ast::ExprKind::TryBlock(_) => {
gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
}
- ast::ExprKind::Closure(box ast::Closure { constness: ast::Const::Yes(_), .. }) => {
- gate_feature_post!(
- &self,
- const_closures,
- e.span,
- "const closures are experimental"
- );
- }
_ => {}
}
visit::walk_expr(self, e)
@@ -501,12 +495,24 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
if let AssocConstraintKind::Bound { .. } = constraint.kind {
- gate_feature_post!(
- &self,
- associated_type_bounds,
- constraint.span,
- "associated type bounds are unstable"
- )
+ if let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
+ && args.inputs.is_empty()
+ && matches!(args.output, ast::FnRetTy::Default(..))
+ {
+ gate_feature_post!(
+ &self,
+ return_type_notation,
+ constraint.span,
+ "return type notation is experimental"
+ );
+ } else {
+ gate_feature_post!(
+ &self,
+ associated_type_bounds,
+ constraint.span,
+ "associated type bounds are unstable"
+ );
+ }
}
visit::walk_assoc_constraint(self, constraint)
}
@@ -524,7 +530,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
);
}
if let Some(ty) = ty {
- self.check_impl_trait(ty);
+ self.check_impl_trait(ty, true);
}
false
}
@@ -594,6 +600,8 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
gate_all!(associated_const_equality, "associated const equality is incomplete");
gate_all!(yeet_expr, "`do yeet` expression is experimental");
+ gate_all!(dyn_star, "`dyn*` trait objects are experimental");
+ gate_all!(const_closures, "const closures are experimental");
// All uses of `gate_all!` below this point were added in #65742,
// and subsequently disabled (with the non-early gating readded).
@@ -609,11 +617,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(trait_alias, "trait aliases are experimental");
gate_all!(associated_type_bounds, "associated type bounds are unstable");
+ gate_all!(return_type_notation, "return type notation is experimental");
gate_all!(decl_macro, "`macro` is experimental");
gate_all!(box_patterns, "box pattern syntax is experimental");
gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");
gate_all!(try_blocks, "`try` blocks are unstable");
- gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
gate_all!(type_ascription, "type ascription is experimental");
visit::walk_crate(&mut visitor, krate);
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index b9dcaee23..e2c666604 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -4,7 +4,6 @@
//!
//! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`.
-#![allow(rustc::potential_query_instability)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_is_partitioned)]
@@ -22,4 +21,4 @@ pub mod feature_gate;
pub mod node_count;
pub mod show_span;
-fluent_messages! { "../locales/en-US.ftl" }
+fluent_messages! { "../messages.ftl" }