From 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:20:39 +0200 Subject: Merging upstream version 1.70.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_ast_passes/locales/en-US.ftl | 236 ----------------------- compiler/rustc_ast_passes/messages.ftl | 237 ++++++++++++++++++++++++ compiler/rustc_ast_passes/src/ast_validation.rs | 79 ++++---- compiler/rustc_ast_passes/src/errors.rs | 14 +- compiler/rustc_ast_passes/src/feature_gate.rs | 92 ++++----- compiler/rustc_ast_passes/src/lib.rs | 3 +- 6 files changed, 338 insertions(+), 323 deletions(-) delete mode 100644 compiler/rustc_ast_passes/locales/en-US.ftl create mode 100644 compiler/rustc_ast_passes/messages.ftl (limited to 'compiler/rustc_ast_passes') diff --git a/compiler/rustc_ast_passes/locales/en-US.ftl b/compiler/rustc_ast_passes/locales/en-US.ftl deleted file mode 100644 index 747bd52b2..000000000 --- a/compiler/rustc_ast_passes/locales/en-US.ftl +++ /dev/null @@ -1,236 +0,0 @@ -ast_passes_forbidden_let = - `let` expressions are not supported here - .note = only supported directly in conditions of `if` and `while` expressions - .not_supported_or = `||` operators are not supported in let chain expressions - .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains - -ast_passes_forbidden_let_stable = - expected expression, found statement (`let`) - .note = variable declaration using `let` is a statement - -ast_passes_deprecated_where_clause_location = - where clause not allowed here - -ast_passes_keyword_lifetime = - lifetimes cannot use keyword names - -ast_passes_invalid_label = - invalid label name `{$name}` - -ast_passes_invalid_visibility = - unnecessary visibility qualifier - .implied = `pub` not permitted here because it's implied - .individual_impl_items = place qualifiers on individual impl items instead - .individual_foreign_items = place qualifiers on individual foreign items instead - -ast_passes_trait_fn_const = - functions in traits cannot be declared const - .label = functions in traits cannot be const - -ast_passes_forbidden_lifetime_bound = - lifetime bounds cannot be used in this context - -ast_passes_forbidden_non_lifetime_param = - only lifetime parameters can be used in this context - -ast_passes_fn_param_too_many = - function can not have more than {$max_num_args} arguments - -ast_passes_fn_param_c_var_args_only = - C-variadic function must be declared with at least one named argument - -ast_passes_fn_param_c_var_args_not_last = - `...` must be the last argument of a C-variadic function - -ast_passes_fn_param_doc_comment = - documentation comments cannot be applied to function parameters - .label = doc comments are not allowed here - -ast_passes_fn_param_forbidden_attr = - allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - -ast_passes_fn_param_forbidden_self = - `self` parameter is only allowed in associated functions - .label = not semantically valid as function parameter - .note = associated functions are those in `impl` or `trait` definitions - -ast_passes_forbidden_default = - `default` is only allowed on items in trait impls - .label = `default` because of this - -ast_passes_assoc_const_without_body = - associated constant in `impl` without body - .suggestion = provide a definition for the constant - -ast_passes_assoc_fn_without_body = - associated function in `impl` without body - .suggestion = provide a definition for the function - -ast_passes_assoc_type_without_body = - associated type in `impl` without body - .suggestion = provide a definition for the type - -ast_passes_const_without_body = - free constant item without body - .suggestion = provide a definition for the constant - -ast_passes_static_without_body = - free static item without body - .suggestion = provide a definition for the static - -ast_passes_ty_alias_without_body = - free type alias without body - .suggestion = provide a definition for the type - -ast_passes_fn_without_body = - free function without a body - .suggestion = provide a definition for the function - -ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block - -ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect - -ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$descr} - .suggestion = remove the {$remove_descr} - .label = `extern` block begins here - -ast_passes_extern_keyword_link = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html - -ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block - .cannot_have = cannot have a body - .invalid = the invalid body - .existing = `extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body - -ast_passes_fn_body_extern = incorrect function inside `extern` block - .cannot_have = cannot have a body - .suggestion = remove the invalid body - .help = you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block - .label = `extern` blocks define existing foreign functions and functions inside of them cannot have a body - -ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers - .label = in this `extern` block - .suggestion = remove the qualifiers - -ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers - .label = in this `extern` block - .note = this limitation may be lifted in the future; see issue #83942 for more information - -ast_passes_bad_c_variadic = only foreign or `unsafe extern "C"` functions may be C-variadic - -ast_passes_item_underscore = `{$kind}` items in this context need a name - .label = `_` is not a valid name for this `{$kind}` item - -ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier - -ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name - .help = consider using the `#[path]` attribute to specify filesystem path - -ast_passes_auto_generic = auto traits cannot have generic parameters - .label = auto trait cannot have generic parameters - .suggestion = remove the parameters - -ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetime bounds - .label = {ast_passes_auto_super_lifetime} - .suggestion = remove the super traits or lifetime bounds - -ast_passes_auto_items = auto traits cannot have associated items - .label = {ast_passes_auto_items} - .suggestion = remove these associated items - -ast_passes_generic_before_constraints = generic arguments must come before the first constraint - .constraints = {$constraint_len -> - [one] constraint - *[other] constraints - } - .args = generic {$args_len -> - [one] argument - *[other] arguments - } - .empty_string = {""}, - .suggestion = move the {$constraint_len -> - [one] constraint - *[other] constraints - } after the generic {$args_len -> - [one] argument - *[other] arguments - } - -ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer types - -ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted - -ast_passes_impl_trait_path = `impl Trait` is not allowed in path parameters - -ast_passes_nested_impl_trait = nested `impl Trait` is not allowed - .outer = outer `impl Trait` - .inner = nested `impl Trait` here - -ast_passes_at_least_one_trait = at least one trait must be specified - -ast_passes_extern_without_abi = extern declarations without an explicit ABI are deprecated - -ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters - .suggestion = reorder the parameters: lifetimes, then consts and types - -ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax - .help = use `auto trait Trait {"{}"}` instead - -ast_passes_unsafe_negative_impl = negative impls cannot be unsafe - .negative = negative because of this - .unsafe = unsafe because of this - -ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation} - .because = {$annotation} because of this - .type = inherent impl for this type - .only_trait = only trait implementations may be annotated with {$annotation} - -ast_passes_unsafe_item = {$kind} cannot be declared unsafe - -ast_passes_fieldless_union = unions cannot have zero fields - -ast_passes_where_after_type_alias = where clauses are not allowed after the type for type aliases - .note = see issue #89122 for more information - -ast_passes_generic_default_trailing = generic parameters with a default must be trailing - -ast_passes_nested_lifetimes = nested quantification of lifetimes - -ast_passes_optional_trait_supertrait = `?Trait` is not permitted in supertraits - .note = traits are `?{$path_str}` by default - -ast_passes_optional_trait_object = `?Trait` is not permitted in trait object types - -ast_passes_tilde_const_disallowed = `~const` is not allowed here - .trait = trait objects cannot have `~const` trait bounds - .closure = closures cannot have `~const` trait bounds - .function = this function is not `const`, so it cannot have `~const` trait bounds - -ast_passes_optional_const_exclusive = `~const` and `?` are mutually exclusive - -ast_passes_const_and_async = functions cannot be both `const` and `async` - .const = `const` because of this - .async = `async` because of this - .label = {""} - -ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations - .label = pattern not allowed in foreign function - -ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies - .label = pattern not allowed in function without body - -ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses - .label = not supported - .suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax - .suggestion_path = if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax - .note = see issue #20041 for more information - -ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library - -ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel - .suggestion = remove the attribute - .stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable - -ast_passes_incompatbile_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed - .help = remove one of these features - -ast_passes_show_span = {$msg} diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl new file mode 100644 index 000000000..a349fe6a3 --- /dev/null +++ b/compiler/rustc_ast_passes/messages.ftl @@ -0,0 +1,237 @@ +ast_passes_forbidden_let = + `let` expressions are not supported here + .note = only supported directly in conditions of `if` and `while` expressions + .not_supported_or = `||` operators are not supported in let chain expressions + .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains + +ast_passes_forbidden_let_stable = + expected expression, found statement (`let`) + .note = variable declaration using `let` is a statement + +ast_passes_deprecated_where_clause_location = + where clause not allowed here + +ast_passes_keyword_lifetime = + lifetimes cannot use keyword names + +ast_passes_invalid_label = + invalid label name `{$name}` + +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 + +ast_passes_trait_fn_const = + functions in traits cannot be declared const + .label = functions in traits cannot be const + +ast_passes_forbidden_lifetime_bound = + lifetime bounds cannot be used in this context + +ast_passes_forbidden_non_lifetime_param = + only lifetime parameters can be used in this context + +ast_passes_fn_param_too_many = + function can not have more than {$max_num_args} arguments + +ast_passes_fn_param_c_var_args_only = + C-variadic function must be declared with at least one named argument + +ast_passes_fn_param_c_var_args_not_last = + `...` must be the last argument of a C-variadic function + +ast_passes_fn_param_doc_comment = + documentation comments cannot be applied to function parameters + .label = doc comments are not allowed here + +ast_passes_fn_param_forbidden_attr = + allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + +ast_passes_fn_param_forbidden_self = + `self` parameter is only allowed in associated functions + .label = not semantically valid as function parameter + .note = associated functions are those in `impl` or `trait` definitions + +ast_passes_forbidden_default = + `default` is only allowed on items in trait impls + .label = `default` because of this + +ast_passes_assoc_const_without_body = + associated constant in `impl` without body + .suggestion = provide a definition for the constant + +ast_passes_assoc_fn_without_body = + associated function in `impl` without body + .suggestion = provide a definition for the function + +ast_passes_assoc_type_without_body = + associated type in `impl` without body + .suggestion = provide a definition for the type + +ast_passes_const_without_body = + free constant item without body + .suggestion = provide a definition for the constant + +ast_passes_static_without_body = + free static item without body + .suggestion = provide a definition for the static + +ast_passes_ty_alias_without_body = + free type alias without body + .suggestion = provide a definition for the type + +ast_passes_fn_without_body = + free function without a body + .suggestion = provide a definition for the function + +ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block + +ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect + +ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$descr} + .suggestion = remove the {$remove_descr} + .label = `extern` block begins here + +ast_passes_extern_keyword_link = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block + .cannot_have = cannot have a body + .invalid = the invalid body + .existing = `extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body + +ast_passes_fn_body_extern = incorrect function inside `extern` block + .cannot_have = cannot have a body + .suggestion = remove the invalid body + .help = you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block + .label = `extern` blocks define existing foreign functions and functions inside of them cannot have a body + +ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers + .label = in this `extern` block + .suggestion = remove the qualifiers + +ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers + .label = in this `extern` block + .note = this limitation may be lifted in the future; see issue #83942 for more information + +ast_passes_bad_c_variadic = only foreign or `unsafe extern "C"` functions may be C-variadic + +ast_passes_item_underscore = `{$kind}` items in this context need a name + .label = `_` is not a valid name for this `{$kind}` item + +ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier + +ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name + .help = consider using the `#[path]` attribute to specify filesystem path + +ast_passes_auto_generic = auto traits cannot have generic parameters + .label = auto trait cannot have generic parameters + .suggestion = remove the parameters + +ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetime bounds + .label = {ast_passes_auto_super_lifetime} + .suggestion = remove the super traits or lifetime bounds + +ast_passes_auto_items = auto traits cannot have associated items + .label = {ast_passes_auto_items} + .suggestion = remove these associated items + +ast_passes_generic_before_constraints = generic arguments must come before the first constraint + .constraints = {$constraint_len -> + [one] constraint + *[other] constraints + } + .args = generic {$args_len -> + [one] argument + *[other] arguments + } + .empty_string = {""}, + .suggestion = move the {$constraint_len -> + [one] constraint + *[other] constraints + } after the generic {$args_len -> + [one] argument + *[other] arguments + } + +ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer types + +ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted + +ast_passes_impl_trait_path = `impl Trait` is not allowed in path parameters + +ast_passes_nested_impl_trait = nested `impl Trait` is not allowed + .outer = outer `impl Trait` + .inner = nested `impl Trait` here + +ast_passes_at_least_one_trait = at least one trait must be specified + +ast_passes_extern_without_abi = extern declarations without an explicit ABI are deprecated + +ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters + .suggestion = reorder the parameters: lifetimes, then consts and types + +ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax + .help = use `auto trait Trait {"{}"}` instead + +ast_passes_unsafe_negative_impl = negative impls cannot be unsafe + .negative = negative because of this + .unsafe = unsafe because of this + +ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation} + .because = {$annotation} because of this + .type = inherent impl for this type + .only_trait = only trait implementations may be annotated with {$annotation} + +ast_passes_unsafe_item = {$kind} cannot be declared unsafe + +ast_passes_fieldless_union = unions cannot have zero fields + +ast_passes_where_after_type_alias = where clauses are not allowed after the type for type aliases + .note = see issue #89122 for more information + +ast_passes_generic_default_trailing = generic parameters with a default must be trailing + +ast_passes_nested_lifetimes = nested quantification of lifetimes + +ast_passes_optional_trait_supertrait = `?Trait` is not permitted in supertraits + .note = traits are `?{$path_str}` by default + +ast_passes_optional_trait_object = `?Trait` is not permitted in trait object types + +ast_passes_tilde_const_disallowed = `~const` is not allowed here + .trait = trait objects cannot have `~const` trait bounds + .closure = closures cannot have `~const` trait bounds + .function = this function is not `const`, so it cannot have `~const` trait bounds + +ast_passes_optional_const_exclusive = `~const` and `?` are mutually exclusive + +ast_passes_const_and_async = functions cannot be both `const` and `async` + .const = `const` because of this + .async = `async` because of this + .label = {""} + +ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations + .label = pattern not allowed in foreign function + +ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies + .label = pattern not allowed in function without body + +ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses + .label = not supported + .suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax + .suggestion_path = if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax + .note = see issue #20041 for more information + +ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library + +ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel + .suggestion = remove the attribute + .stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable + +ast_passes_incompatbile_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed + .help = remove one of these features + +ast_passes_show_span = {$msg} 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) { + 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, bool)) { @@ -643,7 +639,7 @@ fn validate_generic_param_order( span: Span, ) { let mut max_param: Option = 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, #[subdiagnostic] - pub note: Option, + 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" } -- cgit v1.2.3