Skip to content

Put spans in all parsed attributes #142813

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions compiler/rustc_attr_data_structures/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,13 @@ pub enum AttributeKind {
Align { align: Align, span: Span },

/// Represents `#[rustc_allow_const_fn_unstable]`.
AllowConstFnUnstable(ThinVec<Symbol>),
AllowConstFnUnstable { features: ThinVec<(Symbol, Span)> },

/// Represents `#[allow_internal_unstable]`.
AllowInternalUnstable(ThinVec<(Symbol, Span)>),
AllowInternalUnstable { features: ThinVec<(Symbol, Span)> },

/// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
AsPtr(Span),
AsPtr { span: Span },

/// Represents `#[rustc_default_body_unstable]`.
BodyStability {
Expand All @@ -217,7 +217,7 @@ pub enum AttributeKind {
},

/// Represents `#[rustc_const_stable_indirect]`.
ConstStabilityIndirect,
ConstStabilityIndirect { span: Span },

/// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute).
Deprecation { deprecation: Deprecation, span: Span },
Expand All @@ -226,14 +226,14 @@ pub enum AttributeKind {
DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol },

/// Represents `#[inline]` and `#[rustc_force_inline]`.
Inline(InlineAttr, Span),
Inline { kind: InlineAttr, span: Span },

/// Represents `#[rustc_macro_transparency]`.
MacroTransparency(Transparency),
MacroTransparency { transparency: Transparency, span: Span },
/// Represents `#[optimize(size|speed)]`
Optimize(OptimizeAttr, Span),
Optimize { kind: OptimizeAttr, span: Span },
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
Repr(ThinVec<(ReprAttr, Span)>),
Repr { reprs: ThinVec<(ReprAttr, Span)> },

/// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`.
Stability {
Expand Down
16 changes: 7 additions & 9 deletions compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::iter;

use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_span::{Span, Symbol, sym};
Expand All @@ -13,24 +11,24 @@ pub(crate) struct AllowInternalUnstableParser;
impl<S: Stage> CombineAttributeParser<S> for AllowInternalUnstableParser {
const PATH: &[Symbol] = &[sym::allow_internal_unstable];
type Item = (Symbol, Span);
const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowInternalUnstable;
const CONVERT: ConvertFn<Self::Item> =
|features| AttributeKind::AllowInternalUnstable { features };
const TEMPLATE: AttributeTemplate = template!(Word, List: "feat1, feat2, ...");

fn extend<'c>(
cx: &'c mut AcceptContext<'_, '_, S>,
args: &'c ArgParser<'_>,
) -> impl IntoIterator<Item = Self::Item> {
parse_unstable(cx, args, <Self as CombineAttributeParser<S>>::PATH[0])
.into_iter()
.zip(iter::repeat(cx.attr_span))
}
}

pub(crate) struct AllowConstFnUnstableParser;
impl<S: Stage> CombineAttributeParser<S> for AllowConstFnUnstableParser {
const PATH: &[Symbol] = &[sym::rustc_allow_const_fn_unstable];
type Item = Symbol;
const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowConstFnUnstable;
type Item = (Symbol, Span);
const CONVERT: ConvertFn<Self::Item> =
|features| AttributeKind::AllowConstFnUnstable { features };
const TEMPLATE: AttributeTemplate = template!(Word, List: "feat1, feat2, ...");

fn extend<'c>(
Expand All @@ -45,7 +43,7 @@ fn parse_unstable<S: Stage>(
cx: &AcceptContext<'_, '_, S>,
args: &ArgParser<'_>,
symbol: Symbol,
) -> impl IntoIterator<Item = Symbol> {
) -> impl IntoIterator<Item = (Symbol, Span)> {
let mut res = Vec::new();

let Some(list) = args.list() else {
Expand All @@ -59,7 +57,7 @@ fn parse_unstable<S: Stage>(
for param in list.mixed() {
let param_span = param.span();
if let Some(ident) = param.meta_item().and_then(|i| i.path().word()) {
res.push(ident.name);
res.push((ident.name, param_span));
} else {
cx.emit_err(session_diagnostics::ExpectsFeatures {
span: param_span,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
return None;
};

let res = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) {
let kind = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) {
Some(sym::size) => OptimizeAttr::Size,
Some(sym::speed) => OptimizeAttr::Speed,
Some(sym::none) => OptimizeAttr::DoNotOptimize,
Expand All @@ -35,6 +35,6 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
}
};

Some(AttributeKind::Optimize(res, cx.attr_span))
Some(AttributeKind::Optimize { kind, span: cx.attr_span })
}
}
15 changes: 8 additions & 7 deletions compiler/rustc_attr_parsing/src/attributes/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser {
const TEMPLATE: AttributeTemplate = template!(Word, List: "always|never");

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
let span = cx.attr_span;
match args {
ArgParser::NoArgs => Some(AttributeKind::Inline(InlineAttr::Hint, cx.attr_span)),
ArgParser::NoArgs => Some(AttributeKind::Inline { kind: InlineAttr::Hint, span }),
ArgParser::List(list) => {
let Some(l) = list.single() else {
cx.expected_single_argument(list.span);
Expand All @@ -31,10 +32,10 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser {

match l.meta_item().and_then(|i| i.path().word_sym()) {
Some(sym::always) => {
Some(AttributeKind::Inline(InlineAttr::Always, cx.attr_span))
Some(AttributeKind::Inline { kind: InlineAttr::Always, span })
}
Some(sym::never) => {
Some(AttributeKind::Inline(InlineAttr::Never, cx.attr_span))
Some(AttributeKind::Inline { kind: InlineAttr::Never, span })
}
_ => {
cx.expected_specific_argument(l.span(), vec!["always", "never"]);
Expand Down Expand Up @@ -89,9 +90,9 @@ impl<S: Stage> SingleAttributeParser<S> for RustcForceInlineParser {
}
};

Some(AttributeKind::Inline(
InlineAttr::Force { attr_span: cx.attr_span, reason },
cx.attr_span,
))
Some(AttributeKind::Inline {
kind: InlineAttr::Force { attr_span: cx.attr_span, reason },
span: cx.attr_span,
})
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ impl<S: Stage> SingleAttributeParser<S> for AsPtrParser {

fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
// FIXME: check that there's no args (this is currently checked elsewhere)
Some(AttributeKind::AsPtr(cx.attr_span))
Some(AttributeKind::AsPtr { span: cx.attr_span })
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub(crate) struct ReprParser;
impl<S: Stage> CombineAttributeParser<S> for ReprParser {
type Item = (ReprAttr, Span);
const PATH: &[Symbol] = &[sym::repr];
const CONVERT: ConvertFn<Self::Item> = AttributeKind::Repr;
const CONVERT: ConvertFn<Self::Item> = |reprs| AttributeKind::Repr { reprs };
// FIXME(jdonszelmann): never used
const TEMPLATE: AttributeTemplate = template!(List: "C");

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ impl<S: Stage> SingleAttributeParser<S> for ConstStabilityIndirectParser {
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;
const TEMPLATE: AttributeTemplate = template!(Word);

fn convert(_cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
Some(AttributeKind::ConstStabilityIndirect)
fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
Some(AttributeKind::ConstStabilityIndirect { span: cx.attr_span })
}
}

Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_attr_parsing/src/attributes/transparency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ impl<S: Stage> SingleAttributeParser<S> for TransparencyParser {
cx.expected_name_value(cx.attr_span, None);
return None;
};
match nv.value_as_str() {
Some(sym::transparent) => Some(Transparency::Transparent),
Some(sym::semiopaque | sym::semitransparent) => Some(Transparency::SemiOpaque),
Some(sym::opaque) => Some(Transparency::Opaque),
Some(_) => {

let transparency = match nv.value_as_str()? {
sym::transparent => Transparency::Transparent,
sym::semiopaque | sym::semitransparent => Transparency::SemiOpaque,
sym::opaque => Transparency::Opaque,
_ => {
cx.expected_specific_argument_strings(
nv.value_span,
vec!["transparent", "semitransparent", "opaque"],
);
None
return None;
}
None => None,
}
.map(AttributeKind::MacroTransparency)
};
Some(AttributeKind::MacroTransparency { transparency, span: cx.attr_span })
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ impl<'a> TraitDef<'a> {
Annotatable::Item(item) => {
let is_packed = matches!(
AttributeParser::parse_limited(cx.sess, &item.attrs, sym::repr, item.span, item.id),
Some(Attribute::Parsed(AttributeKind::Repr(r))) if r.iter().any(|(x, _)| matches!(x, ReprPacked(..)))
Some(Attribute::Parsed(AttributeKind::Repr{reprs})) if reprs.iter().any(|(x, _)| matches!(x, ReprPacked(..)))
);

let newitem = match &item.kind {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {

let inline_span;
(codegen_fn_attrs.inline, inline_span) = if let Some((inline_attr, span)) =
find_attr!(attrs, AttributeKind::Inline(i, span) => (*i, *span))
find_attr!(attrs, AttributeKind::Inline{kind, span} => (*kind, *span))
{
(inline_attr, Some(span))
} else {
Expand All @@ -456,8 +456,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
codegen_fn_attrs.inline = InlineAttr::Never;
}

codegen_fn_attrs.optimize =
find_attr!(attrs, AttributeKind::Optimize(i, _) => *i).unwrap_or(OptimizeAttr::Default);
codegen_fn_attrs.optimize = find_attr!(attrs, AttributeKind::Optimize{kind, ..} => *kind)
.unwrap_or(OptimizeAttr::Default);

// #73631: closures inherit `#[target_feature]` annotations
//
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/check_consts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub fn rustc_allow_const_fn_unstable(
) -> bool {
let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id));

attrs::find_attr!(attrs, attrs::AttributeKind::AllowConstFnUnstable(syms) if syms.contains(&feature_gate))
attrs::find_attr!(attrs, attrs::AttributeKind::AllowConstFnUnstable{features} if features.iter().any(|(f, _)| *f == feature_gate))
}

/// Returns `true` if the given `def_id` (trait or function) is "safe to expose on stable".
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,8 +880,8 @@ impl SyntaxExtension {
is_local: bool,
) -> SyntaxExtension {
let allow_internal_unstable =
find_attr!(attrs, AttributeKind::AllowInternalUnstable(i) => i)
.map(|i| i.as_slice())
find_attr!(attrs, AttributeKind::AllowInternalUnstable{features} => features)
.map(|f| f.as_slice())
.unwrap_or_default();
// FIXME(jdonszelman): allow_internal_unsafe isn't yet new-style
// let allow_internal_unsafe = find_attr!(attrs, AttributeKind::AllowInternalUnsafe);
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,9 @@ pub fn compile_declarative_macro(

check_emission(macro_check::check_meta_variables(&sess.psess, node_id, span, &lhses, &rhses));

let transparency = find_attr!(attrs, AttributeKind::MacroTransparency(x) => *x)
.unwrap_or(Transparency::fallback(macro_rules));
let transparency =
find_attr!(attrs, AttributeKind::MacroTransparency{transparency, .. } => *transparency)
.unwrap_or(Transparency::fallback(macro_rules));

if let Some(guar) = guar {
// To avoid warning noise, only consider the rules of this
Expand Down
27 changes: 24 additions & 3 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1297,12 +1297,33 @@ impl AttributeExt for Attribute {

#[inline]
fn span(&self) -> Span {
use AttributeKind::*;

fn combine(spans: impl IntoIterator<Item = Span>) -> Span {
spans.into_iter().reduce(|a, b| a.to(b)).unwrap_or(DUMMY_SP)
}

match &self {
Attribute::Unparsed(u) => u.span,
// FIXME: should not be needed anymore when all attrs are parsed
Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
Attribute::Parsed(p) => match p {
Confusables { first_span: span, .. }
| ConstStability { span, .. }
| Stability { span, .. }
| ConstStabilityIndirect { span }
| Deprecation { span, .. }
| DocComment { span, .. }
| Align { span, .. }
| AsPtr { span }
| Inline { span, .. }
| BodyStability { span, .. }
| MacroTransparency { span, .. }
| Optimize { span, .. } => *span,
AllowConstFnUnstable { features, .. } | AllowInternalUnstable { features, .. } => {
combine(features.iter().map(|(_, s)| s).copied())
}
Repr { reprs } => combine(reprs.iter().map(|(_, s)| s).copied()),
},
}
}

Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1249,8 +1249,7 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
let repr = def.repr();
if repr.packed() {
if let Some(reprs) =
attrs::find_attr!(tcx.get_all_attrs(def.did()), attrs::AttributeKind::Repr(r) => r)
if let Some(reprs) = attrs::find_attr!(tcx.get_all_attrs(def.did()), attrs::AttributeKind::Repr{reprs} => reprs)
{
for (r, _) in reprs {
if let ReprPacked(pack) = r
Expand Down Expand Up @@ -1469,10 +1468,10 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
if def.variants().is_empty() {
attrs::find_attr!(
tcx.get_all_attrs(def_id),
attrs::AttributeKind::Repr(rs) => {
attrs::AttributeKind::Repr{reprs} => {
struct_span_code_err!(
tcx.dcx(),
rs.first().unwrap().1,
reprs.first().unwrap().1,
E0084,
"unsupported representation for zero-variant enum"
)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/dangling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {
&& let ty = cx.typeck_results().expr_ty(receiver)
&& owns_allocation(cx.tcx, ty)
&& let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
&& find_attr!(cx.tcx.get_all_attrs(fn_id), AttributeKind::AsPtr(_))
&& find_attr!(cx.tcx.get_all_attrs(fn_id), AttributeKind::AsPtr { .. })
{
// FIXME: use `emit_node_lint` when `#[primary_span]` is added.
cx.tcx.emit_node_span_lint(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/nonstandard_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl EarlyLintPass for NonCamelCaseTypes {
fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
let has_repr_c = matches!(
AttributeParser::parse_limited(cx.sess(), &it.attrs, sym::repr, it.span, it.id),
Some(Attribute::Parsed(AttributeKind::Repr(r))) if r.iter().any(|(r, _)| r == &ReprAttr::ReprC)
Some(Attribute::Parsed(AttributeKind::Repr{reprs})) if reprs.iter().any(|(r, _)| r == &ReprAttr::ReprC)
);

if has_repr_c {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1538,7 +1538,8 @@ impl<'tcx> TyCtxt<'tcx> {
field_shuffle_seed ^= user_seed;
}

if let Some(reprs) = attr::find_attr!(self.get_all_attrs(did), AttributeKind::Repr(r) => r)
if let Some(reprs) =
attr::find_attr!(self.get_all_attrs(did), AttributeKind::Repr{reprs} => reprs )
{
for (r, _) in reprs {
flags.insert(match *r {
Expand Down
Loading
Loading