diff options
Diffstat (limited to 'compiler/rustc_ast_passes')
-rw-r--r-- | compiler/rustc_ast_passes/Cargo.toml | 1 | ||||
-rw-r--r-- | compiler/rustc_ast_passes/messages.ftl | 294 | ||||
-rw-r--r-- | compiler/rustc_ast_passes/src/ast_validation.rs | 24 | ||||
-rw-r--r-- | compiler/rustc_ast_passes/src/errors.rs | 17 | ||||
-rw-r--r-- | compiler/rustc_ast_passes/src/feature_gate.rs | 15 | ||||
-rw-r--r-- | compiler/rustc_ast_passes/src/lib.rs | 2 |
6 files changed, 198 insertions, 155 deletions
diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 8bd212073..eb7361235 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -12,6 +12,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_macros = { path = "../rustc_macros" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index a349fe6a3..2f0ac0c2b 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -1,64 +1,3 @@ -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 @@ -71,36 +10,73 @@ ast_passes_assoc_type_without_body = associated type in `impl` without body .suggestion = provide a definition for the type +ast_passes_at_least_one_trait = at least one trait must be specified + +ast_passes_auto_generic = auto traits cannot have generic parameters + .label = auto trait cannot have generic parameters + .suggestion = remove the parameters + +ast_passes_auto_items = auto traits cannot have associated items + .label = {ast_passes_auto_items} + .suggestion = remove these associated items + +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_bad_c_variadic = only foreign or `unsafe extern "C"` functions may be C-variadic + +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_bound_in_context = bounds on `type`s in {$ctx} have no effect + +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_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_constraint_on_negative_bound = + associated type constraints not allowed on negative bounds -ast_passes_ty_alias_without_body = - free type alias without body - .suggestion = provide a definition for the type +ast_passes_deprecated_where_clause_location = + where clause not allowed here -ast_passes_fn_without_body = - free function without a body - .suggestion = provide a definition for the function +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 <https://github.com/rust-lang/rust/issues/20041> for more information 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_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 <https://github.com/rust-lang/rust/issues/83942> for more information + +ast_passes_extern_keyword_link = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html 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_extern_without_abi = extern declarations without an explicit ABI are deprecated -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_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_fieldless_union = unions cannot have zero fields ast_passes_fn_body_extern = incorrect function inside `extern` block .cannot_have = cannot have a body @@ -108,35 +84,50 @@ ast_passes_fn_body_extern = incorrect function inside `extern` block .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_fn_param_c_var_args_not_last = + `...` must be the last argument of a C-variadic function -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 <https://github.com/rust-lang/rust/issues/83942> for more information +ast_passes_fn_param_c_var_args_only = + C-variadic function must be declared with at least one named argument -ast_passes_bad_c_variadic = only foreign or `unsafe extern "C"` functions may be C-variadic +ast_passes_fn_param_doc_comment = + documentation comments cannot be applied to function parameters + .label = doc comments are not allowed here -ast_passes_item_underscore = `{$kind}` items in this context need a name - .label = `_` is not a valid name for this `{$kind}` item +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_nomangle_ascii = `#[no_mangle]` requires ASCII identifier +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_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_fn_param_too_many = + function can not have more than {$max_num_args} arguments -ast_passes_auto_generic = auto traits cannot have generic parameters - .label = auto trait cannot have generic parameters - .suggestion = remove the parameters +ast_passes_fn_without_body = + free function without a body + .suggestion = provide a definition for the function -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_forbidden_default = + `default` is only allowed on items in trait impls + .label = `default` because of this -ast_passes_auto_items = auto traits cannot have associated items - .label = {ast_passes_auto_items} - .suggestion = remove these associated items +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_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_generic_before_constraints = generic arguments must come before the first constraint .constraints = {$constraint_len -> @@ -156,82 +147,97 @@ ast_passes_generic_before_constraints = generic arguments must come before the f *[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_generic_default_trailing = generic parameters with a default must be trailing ast_passes_impl_trait_path = `impl Trait` is not allowed in path parameters +ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed + .help = remove one of these features + +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_invalid_label = + invalid label name `{$name}` + +ast_passes_item_underscore = `{$kind}` items in this context need a name + .label = `_` is not a valid name for this `{$kind}` item + +ast_passes_keyword_lifetime = + lifetimes cannot use keyword names + +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_negative_bound_not_supported = + negative bounds are not supported + 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_nested_lifetimes = nested quantification of lifetimes -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_nomangle_ascii = `#[no_mangle]` requires ASCII identifier 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_optional_const_exclusive = `~const` and `{$modifier}` are mutually exclusive -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_optional_trait_object = `?Trait` is not permitted in trait object types -ast_passes_unsafe_item = {$kind} cannot be declared unsafe +ast_passes_optional_trait_supertrait = `?Trait` is not permitted in supertraits + .note = traits are `?{$path_str}` by default -ast_passes_fieldless_union = unions cannot have zero fields +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_where_after_type_alias = where clauses are not allowed after the type for type aliases - .note = see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information +ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies + .label = pattern not allowed in function without body -ast_passes_generic_default_trailing = generic parameters with a default must be trailing +ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer types -ast_passes_nested_lifetimes = nested quantification of lifetimes +ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations + .label = pattern not allowed in foreign function -ast_passes_optional_trait_supertrait = `?Trait` is not permitted in supertraits - .note = traits are `?{$path_str}` by default +ast_passes_show_span = {$msg} -ast_passes_optional_trait_object = `?Trait` is not permitted in trait object types +ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library + +ast_passes_static_without_body = + free static item without body + .suggestion = provide a definition for the static 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_trait_fn_const = + functions in traits cannot be declared const + .label = functions in traits cannot be const -ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies - .label = pattern not allowed in function without body +ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted -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 <https://github.com/rust-lang/rust/issues/20041> for more information +ast_passes_ty_alias_without_body = + free type alias without body + .suggestion = provide a definition for the type -ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library +ast_passes_unsafe_item = {$kind} cannot be declared unsafe -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_unsafe_negative_impl = negative impls cannot be unsafe + .negative = negative because of this + .unsafe = unsafe because of this -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_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_show_span = {$msg} +ast_passes_where_after_type_alias = where clauses are not allowed after the type for type aliases + .note = see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index c79626ccd..04ed27678 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -348,7 +348,7 @@ impl<'a> AstValidator<'a> { let source_map = self.session.source_map(); let end = source_map.end_point(sp); - if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) { + if source_map.span_to_snippet(end).is_ok_and(|s| s == ";") { end } else { sp.shrink_to_hi() @@ -736,11 +736,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { this.visit_expr(&arm.body); this.visit_pat(&arm.pat); walk_list!(this, visit_attribute, &arm.attrs); - if let Some(guard) = &arm.guard && let ExprKind::Let(_, guard_expr, _) = &guard.kind { + if let Some(guard) = &arm.guard { this.with_let_management(None, |this, _| { - this.visit_expr(guard_expr) + this.visit_expr(guard) }); - return; } } } @@ -1168,12 +1167,27 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }); } (_, TraitBoundModifier::MaybeConstMaybe) => { - self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span()}); + self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "?" }); + } + (_, TraitBoundModifier::MaybeConstNegative) => { + self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span(), modifier: "!" }); } _ => {} } } + // Negative trait bounds are not allowed to have associated constraints + if let GenericBound::Trait(trait_ref, TraitBoundModifier::Negative) = bound + && let Some(segment) = trait_ref.trait_ref.path.segments.last() + && let Some(ast::GenericArgs::AngleBracketed(args)) = segment.args.as_deref() + { + for arg in &args.args { + if let ast::AngleBracketedArg::Constraint(constraint) = arg { + self.err_handler().emit_err(errors::ConstraintOnNegativeBound { span: constraint.span }); + } + } + } + visit::walk_param_bound(self, bound) } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 27bbd2379..82fe2a21d 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -567,6 +567,7 @@ pub enum TildeConstReason { pub struct OptionalConstExclusive { #[primary_span] pub span: Span, + pub modifier: &'static str, } #[derive(Diagnostic)] @@ -677,7 +678,7 @@ impl AddToDiagnostic for StableFeature { } #[derive(Diagnostic)] -#[diag(ast_passes_incompatbile_features)] +#[diag(ast_passes_incompatible_features)] #[help] pub struct IncompatibleFeatures { #[primary_span] @@ -693,3 +694,17 @@ pub struct ShowSpan { pub span: Span, pub msg: &'static str, } + +#[derive(Diagnostic)] +#[diag(ast_passes_negative_bound_not_supported)] +pub struct NegativeBoundUnsupported { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_constraint_on_negative_bound)] +pub struct ConstraintOnNegativeBound { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 17bcd24ee..274f931e4 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -83,7 +83,7 @@ impl<'a> PostExpansionVisitor<'a> { &self, const_extern_fn, span, - &format!("`{}` as a `const fn` ABI is unstable", abi) + format!("`{}` as a `const fn` ABI is unstable", abi) ), } } @@ -104,7 +104,7 @@ impl<'a> PostExpansionVisitor<'a> { if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) { self.sess.parse_sess.span_diagnostic.delay_span_bug( span, - &format!( + format!( "unrecognized ABI not caught in lowering: {}", symbol_unescaped.as_str() ), @@ -317,8 +317,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match i.kind { ast::ForeignItemKind::Fn(..) | ast::ForeignItemKind::Static(..) => { 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.")); + let links_to_llvm = link_name.is_some_and(|val| val.as_str().starts_with("llvm.")); if links_to_llvm { gate_feature_post!( &self, @@ -572,6 +571,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { } }; } + gate_all!(c_str_literals, "`c\"..\"` literals are experimental"); gate_all!( if_let_guard, "`if let` guards are experimental", @@ -602,6 +602,13 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { 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"); + gate_all!(builtin_syntax, "`builtin #` syntax is unstable"); + + if !visitor.features.negative_bounds { + for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() { + sess.emit_err(errors::NegativeBoundUnsupported { span }); + } + } // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index e2c666604..7db413c5b 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -13,7 +13,7 @@ #![deny(rustc::diagnostic_outside_of_impl)] use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; pub mod ast_validation; mod errors; |