From 17d40c6057c88f4c432b0d7bac88e1b84cb7e67f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:03:36 +0200 Subject: Adding upstream version 1.65.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_attr/src/builtin.rs | 398 ++++++++++++++++--------------------- 1 file changed, 168 insertions(+), 230 deletions(-) (limited to 'compiler/rustc_attr/src/builtin.rs') diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 10a9cfb62..753f62dd5 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -3,7 +3,6 @@ use rustc_ast as ast; use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem, NodeId}; use rustc_ast_pretty::pprust; -use rustc_errors::{struct_span_err, Applicability}; use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg}; use rustc_macros::HashStable_Generic; use rustc_session::lint::builtin::UNEXPECTED_CFGS; @@ -14,6 +13,20 @@ use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; use std::num::NonZeroU32; +use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause}; + +/// The version placeholder that recently stabilized features contain inside the +/// `since` field of the `#[stable]` attribute. +/// +/// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591). +pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION"; + +pub fn rust_version_symbol() -> Symbol { + let version = option_env!("CFG_VERSION").unwrap_or(""); + let version = version.split(' ').next().unwrap(); + Symbol::intern(&version) +} + pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() } @@ -25,46 +38,43 @@ enum AttrError { NonIdentFeature, MissingFeature, MultipleStabilityLevels, - UnsupportedLiteral(&'static str, /* is_bytestr */ bool), + UnsupportedLiteral(UnsupportedLiteralReason, /* is_bytestr */ bool), +} + +pub(crate) enum UnsupportedLiteralReason { + Generic, + CfgString, + DeprecatedString, + DeprecatedKvPair, } fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { - let diag = &sess.span_diagnostic; match error { AttrError::MultipleItem(item) => { - struct_span_err!(diag, span, E0538, "multiple '{}' items", item).emit(); + sess.emit_err(session_diagnostics::MultipleItem { span, item }); } AttrError::UnknownMetaItem(item, expected) => { - let expected = expected.iter().map(|name| format!("`{}`", name)).collect::>(); - struct_span_err!(diag, span, E0541, "unknown meta item '{}'", item) - .span_label(span, format!("expected one of {}", expected.join(", "))) - .emit(); + sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected }); } AttrError::MissingSince => { - struct_span_err!(diag, span, E0542, "missing 'since'").emit(); + sess.emit_err(session_diagnostics::MissingSince { span }); } AttrError::NonIdentFeature => { - struct_span_err!(diag, span, E0546, "'feature' is not an identifier").emit(); + sess.emit_err(session_diagnostics::NonIdentFeature { span }); } AttrError::MissingFeature => { - struct_span_err!(diag, span, E0546, "missing 'feature'").emit(); + sess.emit_err(session_diagnostics::MissingFeature { span }); } AttrError::MultipleStabilityLevels => { - struct_span_err!(diag, span, E0544, "multiple stability levels").emit(); + sess.emit_err(session_diagnostics::MultipleStabilityLevels { span }); } - AttrError::UnsupportedLiteral(msg, is_bytestr) => { - let mut err = struct_span_err!(diag, span, E0565, "{}", msg); - if is_bytestr { - if let Ok(lint_str) = sess.source_map().span_to_snippet(span) { - err.span_suggestion( - span, - "consider removing the prefix", - &lint_str[1..], - Applicability::MaybeIncorrect, - ); - } - } - err.emit(); + AttrError::UnsupportedLiteral(reason, is_bytestr) => { + sess.emit_err(session_diagnostics::UnsupportedLiteral { + span, + reason, + is_bytestr, + start_point_span: sess.source_map().start_point(span), + }); } } } @@ -131,6 +141,14 @@ impl ConstStability { } } +/// Represents the `#[rustc_default_body_unstable]` attribute. +#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(HashStable_Generic)] +pub struct DefaultBodyStability { + pub level: StabilityLevel, + pub feature: Symbol, +} + /// The available stability levels. #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(HashStable_Generic)] @@ -214,7 +232,8 @@ pub fn find_stability( sess: &Session, attrs: &[Attribute], item_sp: Span, -) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>) { +) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>) +{ find_stability_generic(sess, attrs.iter(), item_sp) } @@ -222,7 +241,7 @@ fn find_stability_generic<'a, I>( sess: &Session, attrs_iter: I, item_sp: Span, -) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>) +) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>) where I: Iterator, { @@ -230,11 +249,10 @@ where let mut stab: Option<(Stability, Span)> = None; let mut const_stab: Option<(ConstStability, Span)> = None; + let mut body_stab: Option<(DefaultBodyStability, Span)> = None; let mut promotable = false; let mut allowed_through_unstable_modules = false; - let diagnostic = &sess.parse_sess.span_diagnostic; - 'outer: for attr in attrs_iter { if ![ sym::rustc_const_unstable, @@ -243,6 +261,7 @@ where sym::stable, sym::rustc_promotable, sym::rustc_allowed_through_unstable_modules, + sym::rustc_default_body_unstable, ] .iter() .any(|&s| attr.has_name(s)) @@ -273,14 +292,14 @@ where *item = Some(v); true } else { - struct_span_err!(diagnostic, meta.span, E0539, "incorrect meta item").emit(); + sess.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); false } }; let meta_name = meta.name_or_empty(); match meta_name { - sym::rustc_const_unstable | sym::unstable => { + sym::rustc_const_unstable | sym::rustc_default_body_unstable | sym::unstable => { if meta_name == sym::unstable && stab.is_some() { handle_errors( &sess.parse_sess, @@ -295,6 +314,13 @@ where AttrError::MultipleStabilityLevels, ); break; + } else if meta_name == sym::rustc_default_body_unstable && body_stab.is_some() { + handle_errors( + &sess.parse_sess, + attr.span, + AttrError::MultipleStabilityLevels, + ); + break; } let mut feature = None; @@ -308,7 +334,7 @@ where handle_errors( &sess.parse_sess, meta.span(), - AttrError::UnsupportedLiteral("unsupported literal", false), + AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), ); continue 'outer; }; @@ -332,39 +358,28 @@ where // is a name/value pair string literal. issue_num = match issue.unwrap().as_str() { "none" => None, - issue => { - let emit_diag = |msg: &str| { - struct_span_err!( - diagnostic, - mi.span, - E0545, - "`issue` must be a non-zero numeric string \ - or \"none\"", - ) - .span_label(mi.name_value_literal_span().unwrap(), msg) - .emit(); - }; - match issue.parse() { - Ok(0) => { - emit_diag( - "`issue` must not be \"0\", \ - use \"none\" instead", - ); - continue 'outer; - } - Ok(num) => NonZeroU32::new(num), - Err(err) => { - emit_diag(&err.to_string()); - continue 'outer; - } + issue => match issue.parse::() { + Ok(num) => Some(num), + Err(err) => { + sess.emit_err( + session_diagnostics::InvalidIssueString { + span: mi.span, + cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind( + mi.name_value_literal_span().unwrap(), + err.kind(), + ), + }, + ); + continue 'outer; } - } + }, }; } sym::soft => { if !mi.is_word() { - let msg = "`soft` should not have any arguments"; - sess.parse_sess.span_diagnostic.span_err(mi.span, msg); + sess.emit_err(session_diagnostics::SoftNoArgs { + span: mi.span, + }); } is_soft = true; } @@ -405,11 +420,16 @@ where }; if sym::unstable == meta_name { stab = Some((Stability { level, feature }, attr.span)); - } else { + } else if sym::rustc_const_unstable == meta_name { const_stab = Some(( ConstStability { level, feature, promotable: false }, attr.span, )); + } else if sym::rustc_default_body_unstable == meta_name { + body_stab = + Some((DefaultBodyStability { level, feature }, attr.span)); + } else { + unreachable!("Unknown stability attribute {meta_name}"); } } (None, _, _) => { @@ -417,8 +437,7 @@ where continue; } _ => { - struct_span_err!(diagnostic, attr.span, E0547, "missing 'issue'") - .emit(); + sess.emit_err(session_diagnostics::MissingIssue { span: attr.span }); continue; } } @@ -471,13 +490,20 @@ where handle_errors( &sess.parse_sess, lit.span, - AttrError::UnsupportedLiteral("unsupported literal", false), + AttrError::UnsupportedLiteral( + UnsupportedLiteralReason::Generic, + false, + ), ); continue 'outer; } } } + if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER { + since = Some(rust_version_symbol()); + } + match (feature, since) { (Some(feature), Some(since)) => { let level = Stable { since, allowed_through_unstable_modules: false }; @@ -510,14 +536,7 @@ where if let Some((ref mut stab, _)) = const_stab { stab.promotable = promotable; } else { - struct_span_err!( - diagnostic, - item_sp, - E0717, - "`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` \ - or a `rustc_const_stable` attribute" - ) - .emit(); + sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }); } } @@ -532,17 +551,11 @@ where { *allowed_through_unstable_modules = true; } else { - struct_span_err!( - diagnostic, - item_sp, - E0789, - "`rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute" - ) - .emit(); + sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp }); } } - (stab, const_stab) + (stab, const_stab, body_stab) } pub fn find_crate_name(sess: &Session, attrs: &[Attribute]) -> Option { @@ -652,25 +665,18 @@ pub fn eval_condition( NestedMetaItem::Literal(Lit { span, .. }) | NestedMetaItem::MetaItem(MetaItem { span, .. }), ] => { - sess.span_diagnostic - .struct_span_err(*span, "expected a version literal") - .emit(); + sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span }); return false; } [..] => { - sess.span_diagnostic - .struct_span_err(cfg.span, "expected single version literal") - .emit(); + sess.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { + span: cfg.span, + }); return false; } }; let Some(min_version) = parse_version(min_version.as_str(), false) else { - sess.span_diagnostic - .struct_span_warn( - *span, - "unknown version literal format, assuming it refers to a future version", - ) - .emit(); + sess.emit_warning(session_diagnostics::UnknownVersionLiteral { span: *span }); return false; }; let rustc_version = parse_version(env!("CFG_RELEASE"), true).unwrap(); @@ -688,7 +694,7 @@ pub fn eval_condition( handle_errors( sess, mi.span(), - AttrError::UnsupportedLiteral("unsupported literal", false), + AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), ); return false; } @@ -713,13 +719,9 @@ pub fn eval_condition( }), sym::not => { if mis.len() != 1 { - struct_span_err!( - sess.span_diagnostic, - cfg.span, - E0536, - "expected 1 cfg-pattern" - ) - .emit(); + sess.emit_err(session_diagnostics::ExpectedOneCfgPattern { + span: cfg.span, + }); return false; } @@ -745,21 +747,16 @@ pub fn eval_condition( }) } _ => { - struct_span_err!( - sess.span_diagnostic, - cfg.span, - E0537, - "invalid predicate `{}`", - pprust::path_to_string(&cfg.path) - ) - .emit(); + sess.emit_err(session_diagnostics::InvalidPredicate { + span: cfg.span, + predicate: pprust::path_to_string(&cfg.path), + }); false } } } ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => { - sess.span_diagnostic - .span_err(cfg.path.span, "`cfg` predicate key must be an identifier"); + sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span }); true } MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => { @@ -767,7 +764,7 @@ pub fn eval_condition( sess, lit.span, AttrError::UnsupportedLiteral( - "literal in `cfg` predicate value must be a string", + UnsupportedLiteralReason::CfgString, lit.kind.is_bytestr(), ), ); @@ -811,7 +808,6 @@ where I: Iterator, { let mut depr: Option<(Deprecation, Span)> = None; - let diagnostic = &sess.parse_sess.span_diagnostic; let is_rustc = sess.features_untracked().staged_api; 'outer: for attr in attrs_iter { @@ -847,14 +843,14 @@ where &sess.parse_sess, lit.span, AttrError::UnsupportedLiteral( - "literal in `deprecated` \ - value must be a string", + UnsupportedLiteralReason::DeprecatedString, lit.kind.is_bytestr(), ), ); } else { - struct_span_err!(diagnostic, meta.span, E0551, "incorrect meta item") - .emit(); + sess.emit_err(session_diagnostics::IncorrectMetaItem2 { + span: meta.span, + }); } false @@ -876,14 +872,11 @@ where } sym::suggestion => { if !sess.features_untracked().deprecated_suggestion { - let mut diag = sess.struct_span_err( - mi.span, - "suggestions on deprecated items are unstable", - ); - if sess.is_nightly_build() { - diag.help("add `#![feature(deprecated_suggestion)]` to the crate root"); - } - diag.note("see #94785 for more details").emit(); + sess.emit_err(session_diagnostics::DeprecatedItemSuggestion { + span: mi.span, + is_nightly: sess.is_nightly_build().then_some(()), + details: (), + }); } if !get(mi, &mut suggestion) { @@ -911,7 +904,7 @@ where &sess.parse_sess, lit.span, AttrError::UnsupportedLiteral( - "item in `deprecated` must be a key/value pair", + UnsupportedLiteralReason::DeprecatedKvPair, false, ), ); @@ -929,7 +922,7 @@ where } if note.is_none() { - struct_span_err!(diagnostic, attr.span, E0543, "missing 'note'").emit(); + sess.emit_err(session_diagnostics::MissingNote { span: attr.span }); continue; } } @@ -999,19 +992,9 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { sym::simd => Some(ReprSimd), sym::transparent => Some(ReprTransparent), sym::align => { - let mut err = struct_span_err!( - diagnostic, - item.span(), - E0589, - "invalid `repr(align)` attribute: `align` needs an argument" - ); - err.span_suggestion( - item.span(), - "supply an argument here", - "align(...)", - Applicability::HasPlaceholders, - ); - err.emit(); + sess.emit_err(session_diagnostics::InvalidReprAlignNeedArg { + span: item.span(), + }); recognised = true; None } @@ -1040,109 +1023,64 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { || int_type_of_word(name).is_some() { recognised = true; - struct_span_err!( - diagnostic, - item.span(), - E0552, - "invalid representation hint: `{}` does not take a parenthesized argument list", - name.to_ident_string(), - ).emit(); + sess.emit_err(session_diagnostics::InvalidReprHintNoParen { + span: item.span(), + name: name.to_ident_string(), + }); } if let Some(literal_error) = literal_error { - struct_span_err!( - diagnostic, - item.span(), - E0589, - "invalid `repr({})` attribute: {}", - name.to_ident_string(), - literal_error - ) - .emit(); + sess.emit_err(session_diagnostics::InvalidReprGeneric { + span: item.span(), + repr_arg: name.to_ident_string(), + error_part: literal_error, + }); } } else if let Some(meta_item) = item.meta_item() { if let MetaItemKind::NameValue(ref value) = meta_item.kind { if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) { let name = meta_item.name_or_empty().to_ident_string(); recognised = true; - let mut err = struct_span_err!( - diagnostic, - item.span(), - E0693, - "incorrect `repr({})` attribute format", - name, - ); - match value.kind { - ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => { - err.span_suggestion( - item.span(), - "use parentheses instead", - format!("{}({})", name, int), - Applicability::MachineApplicable, - ); - } - ast::LitKind::Str(s, _) => { - err.span_suggestion( - item.span(), - "use parentheses instead", - format!("{}({})", name, s), - Applicability::MachineApplicable, - ); - } - _ => {} - } - err.emit(); - } else { - if matches!( - meta_item.name_or_empty(), - sym::C | sym::simd | sym::transparent - ) || int_type_of_word(meta_item.name_or_empty()).is_some() - { - recognised = true; - struct_span_err!( - diagnostic, - meta_item.span, - E0552, - "invalid representation hint: `{}` does not take a value", - meta_item.name_or_empty().to_ident_string(), - ) - .emit(); - } + sess.emit_err(session_diagnostics::IncorrectReprFormatGeneric { + span: item.span(), + repr_arg: &name, + cause: IncorrectReprFormatGenericCause::from_lit_kind( + item.span(), + &value.kind, + &name, + ), + }); + } else if matches!( + meta_item.name_or_empty(), + sym::C | sym::simd | sym::transparent + ) || int_type_of_word(meta_item.name_or_empty()).is_some() + { + recognised = true; + sess.emit_err(session_diagnostics::InvalidReprHintNoValue { + span: meta_item.span, + name: meta_item.name_or_empty().to_ident_string(), + }); } } else if let MetaItemKind::List(_) = meta_item.kind { if meta_item.has_name(sym::align) { recognised = true; - struct_span_err!( - diagnostic, - meta_item.span, - E0693, - "incorrect `repr(align)` attribute format: \ - `align` takes exactly one argument in parentheses" - ) - .emit(); + sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg { + span: meta_item.span, + }); } else if meta_item.has_name(sym::packed) { recognised = true; - struct_span_err!( - diagnostic, - meta_item.span, - E0552, - "incorrect `repr(packed)` attribute format: \ - `packed` takes exactly one parenthesized argument, \ - or no parentheses at all" - ) - .emit(); + sess.emit_err(session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg { + span: meta_item.span, + }); } else if matches!( meta_item.name_or_empty(), sym::C | sym::simd | sym::transparent ) || int_type_of_word(meta_item.name_or_empty()).is_some() { recognised = true; - struct_span_err!( - diagnostic, - meta_item.span, - E0552, - "invalid representation hint: `{}` does not take a parenthesized argument list", - meta_item.name_or_empty().to_ident_string(), - ).emit(); + sess.emit_err(session_diagnostics::InvalidReprHintNoParen { + span: meta_item.span, + name: meta_item.name_or_empty().to_ident_string(), + }); } } } @@ -1239,10 +1177,10 @@ fn allow_unstable<'a>( let list = attrs .filter_map(move |attr| { attr.meta_item_list().or_else(|| { - sess.diagnostic().span_err( - attr.span, - &format!("`{}` expects a list of feature names", symbol.to_ident_string()), - ); + sess.emit_err(session_diagnostics::ExpectsFeatureList { + span: attr.span, + name: symbol.to_ident_string(), + }); None }) }) @@ -1251,10 +1189,10 @@ fn allow_unstable<'a>( list.into_iter().filter_map(move |it| { let name = it.ident().map(|ident| ident.name); if name.is_none() { - sess.diagnostic().span_err( - it.span(), - &format!("`{}` expects feature names", symbol.to_ident_string()), - ); + sess.emit_err(session_diagnostics::ExpectsFeatures { + span: it.span(), + name: symbol.to_ident_string(), + }); } name }) -- cgit v1.2.3