Skip to content

Fix ICE caused by parsed attributes applied to where bounds #143781

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
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
10 changes: 5 additions & 5 deletions compiler/rustc_attr_data_structures/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ pub enum AttributeKind {
},

/// Represents `#[rustc_const_stable_indirect]`.
ConstStabilityIndirect,
ConstStabilityIndirect(Span),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this issue by giving all AttributeKind variants a span. I think this is the better way, the alternative would be removing the span from all variants and adding it to Attribute::Parsed.

I went for this approach because:

  1. I think Attribute::Unparsed is probably going away in the future anyways? (not sure, cc @jdonszelmann)
  2. Putting the span in Attribute::Unparsed means the find_attr! macro no longer has access to it. This could be fixed by giving the macro the span as a separate argument but that makes the macro calls quite a bit uglier


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

/// Represents `#[rustc_dummy]`.
Dummy,
Dummy(Span),

/// Represents [`#[export_name]`](https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute).
ExportName {
Expand All @@ -252,7 +252,7 @@ pub enum AttributeKind {
},

/// Represents `#[export_stable]`.
ExportStable,
ExportStable(Span),

/// Represents `#[ffi_const]`.
FfiConst(Span),
Expand Down Expand Up @@ -280,7 +280,7 @@ pub enum AttributeKind {
LoopMatch(Span),

/// Represents `#[rustc_macro_transparency]`.
MacroTransparency(Transparency),
MacroTransparency(Transparency, Span),

/// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html).
MayDangle(Span),
Expand Down Expand Up @@ -326,7 +326,7 @@ pub enum AttributeKind {
RustcLayoutScalarValidRangeStart(Box<u128>, Span),

/// Represents `#[rustc_object_lifetime_default]`.
RustcObjectLifetimeDefault,
RustcObjectLifetimeDefault(Span),

/// Represents `#[rustc_skip_during_method_dispatch]`.
SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span },
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_attr_data_structures/src/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ impl AttributeKind {
Confusables { .. } => Yes,
ConstContinue(..) => No,
ConstStability { .. } => Yes,
ConstStabilityIndirect => No,
ConstStabilityIndirect(..) => No,
Deprecation { .. } => Yes,
DocComment { .. } => Yes,
Dummy => No,
Dummy(..) => No,
ExportName { .. } => Yes,
ExportStable => No,
ExportStable(..) => No,
FfiConst(..) => No,
FfiPure(..) => No,
Ignore { .. } => No,
Expand All @@ -49,7 +49,7 @@ impl AttributeKind {
Repr { .. } => No,
RustcLayoutScalarValidRangeEnd(..) => Yes,
RustcLayoutScalarValidRangeStart(..) => Yes,
RustcObjectLifetimeDefault => No,
RustcObjectLifetimeDefault(..) => No,
SkipDuringMethodDispatch { .. } => No,
Stability { .. } => Yes,
StdInternalSymbol(..) => No,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl<S: Stage> SingleAttributeParser<S> for DummyParser {
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;
const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really

fn convert(_: &mut AcceptContext<'_, '_, S>, _: &ArgParser<'_>) -> Option<AttributeKind> {
Some(AttributeKind::Dummy)
fn convert(cx: &mut AcceptContext<'_, '_, S>, _: &ArgParser<'_>) -> Option<AttributeKind> {
Some(AttributeKind::Dummy(cx.attr_span))
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub(crate) struct ExportStableParser;
impl<S: Stage> NoArgsAttributeParser<S> for ExportStableParser {
const PATH: &[Symbol] = &[sym::export_stable];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable;
const CREATE: fn(Span) -> AttributeKind = AttributeKind::ExportStable;
}

pub(crate) struct FfiConstParser;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@ impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {
return None;
}

Some(AttributeKind::RustcObjectLifetimeDefault)
Some(AttributeKind::RustcObjectLifetimeDefault(cx.attr_span))
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub(crate) struct ConstStabilityIndirectParser;
impl<S: Stage> NoArgsAttributeParser<S> for ConstStabilityIndirectParser {
const PATH: &[Symbol] = &[sym::rustc_const_stable_indirect];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ConstStabilityIndirect;
const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstStabilityIndirect;
}

#[derive(Default)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/transparency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ impl<S: Stage> SingleAttributeParser<S> for TransparencyParser {
}
None => None,
}
.map(AttributeKind::MacroTransparency)
.map(|t| AttributeKind::MacroTransparency(t, cx.attr_span))
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ pub fn compile_declarative_macro(
return dummy_syn_ext(guar);
}

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

if let Some(guar) = guar {
Expand Down
51 changes: 45 additions & 6 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1299,12 +1299,51 @@ impl AttributeExt for Attribute {
fn span(&self) -> Span {
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,
Attribute::Parsed(AttributeKind::MayDangle(span)) => *span,
Attribute::Parsed(AttributeKind::Ignore { span, .. }) => *span,
a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
Attribute::Parsed(kind) => match kind {
AttributeKind::Align { span, .. }
| AttributeKind::AllowConstFnUnstable(_, span)
| AttributeKind::AllowInternalUnstable(_, span)
| AttributeKind::AsPtr(span)
| AttributeKind::BodyStability { span, .. }
| AttributeKind::Cold(span)
| AttributeKind::Confusables { first_span: span, .. }
| AttributeKind::ConstContinue(span)
| AttributeKind::ConstStability { span, .. }
| AttributeKind::ConstStabilityIndirect(span)
| AttributeKind::Deprecation { span, .. }
| AttributeKind::DocComment { span, .. }
| AttributeKind::Dummy(span)
| AttributeKind::ExportName { span, .. }
| AttributeKind::ExportStable(span)
| AttributeKind::FfiConst(span)
| AttributeKind::FfiPure(span)
| AttributeKind::Ignore { span, .. }
| AttributeKind::Inline(_, span)
| AttributeKind::LinkName { span, .. }
| AttributeKind::LinkSection { span, .. }
| AttributeKind::LoopMatch(span)
| AttributeKind::MacroTransparency(.., span)
| AttributeKind::MayDangle(span)
| AttributeKind::MustUse { span, .. }
| AttributeKind::Naked(span)
| AttributeKind::NoImplicitPrelude(span)
| AttributeKind::NoMangle(span)
| AttributeKind::NonExhaustive(span)
| AttributeKind::Optimize(_, span)
| AttributeKind::PassByValue(span)
| AttributeKind::Path(_, span)
| AttributeKind::PubTransparent(span)
| AttributeKind::Repr { first_span: span, .. }
| AttributeKind::RustcLayoutScalarValidRangeEnd(_, span)
| AttributeKind::RustcLayoutScalarValidRangeStart(_, span)
| AttributeKind::RustcObjectLifetimeDefault(span)
| AttributeKind::SkipDuringMethodDispatch { span, .. }
| AttributeKind::Stability { span, .. }
| AttributeKind::StdInternalSymbol(span)
| AttributeKind::TargetFeature(_, span)
| AttributeKind::TrackCaller(span)
| AttributeKind::Used { span, .. } => *span,
},
}
}

Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
Attribute::Parsed(AttributeKind::Repr { .. }) => { /* handled below this loop and elsewhere */
}
Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault) => {
Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault(..)) => {
self.check_object_lifetime_default(hir_id);
}
&Attribute::Parsed(AttributeKind::PubTransparent(attr_span)) => {
Expand Down Expand Up @@ -204,7 +204,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span)
| AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span),
) => self.check_rustc_layout_scalar_valid_range(*attr_span, span, target),
Attribute::Parsed(AttributeKind::ExportStable) => {
Attribute::Parsed(AttributeKind::ExportStable(..)) => {
// handled in `check_export`
}
&Attribute::Parsed(AttributeKind::FfiConst(attr_span)) => {
Expand All @@ -215,9 +215,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
Attribute::Parsed(
AttributeKind::BodyStability { .. }
| AttributeKind::ConstStabilityIndirect
| AttributeKind::MacroTransparency(_)
| AttributeKind::Dummy,
| AttributeKind::ConstStabilityIndirect(..)
| AttributeKind::MacroTransparency(..)
| AttributeKind::Dummy(..),
) => { /* do nothing */ }
Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_passes/src/check_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl<'tcx> ExportableItemCollector<'tcx> {
}

fn item_is_exportable(&self, def_id: LocalDefId) -> bool {
let has_attr = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable);
let has_attr = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable(..));
if !self.in_exportable_mod && !has_attr {
return false;
}
Expand Down Expand Up @@ -81,7 +81,7 @@ impl<'tcx> ExportableItemCollector<'tcx> {
fn walk_item_with_mod(&mut self, item: &'tcx hir::Item<'tcx>) {
let def_id = item.hir_id().owner.def_id;
let old_exportable_mod = self.in_exportable_mod;
if find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable) {
if find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable(..)) {
self.in_exportable_mod = true;
}
let old_seen_exportable_in_mod = std::mem::replace(&mut self.seen_exportable_in_mod, false);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);

let depr = attrs::find_attr!(attrs, AttributeKind::Deprecation{deprecation, span} => (*deprecation, *span));
let const_stability_indirect = find_attr!(attrs, AttributeKind::ConstStabilityIndirect);
let const_stability_indirect = find_attr!(attrs, AttributeKind::ConstStabilityIndirect(..));

let mut is_deprecated = false;
if let Some((depr, span)) = &depr {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
let hir_id = self.tcx.local_def_id_to_hir_id(local_def_id);
let attrs = self.tcx.hir_attrs(hir_id);

if attrs::find_attr!(attrs, attrs::AttributeKind::MacroTransparency(x) => *x)
if attrs::find_attr!(attrs, attrs::AttributeKind::MacroTransparency(x, _) => *x)
.unwrap_or(Transparency::fallback(md.macro_rules))
!= Transparency::Opaque
{
Expand Down
7 changes: 0 additions & 7 deletions tests/crashes/138510.rs

This file was deleted.

12 changes: 12 additions & 0 deletions tests/ui/where-clauses/unsupported_attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#![feature(custom_test_frameworks)]
#![feature(derive_const)]
#![feature(where_clause_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(soft_unstable)]

trait Trait {}
Expand Down Expand Up @@ -33,4 +34,15 @@ where
//~| ERROR expected non-macro attribute, found attribute macro `derive`
#[rustfmt::skip] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
#[rustfmt::skip] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
#[must_use] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
#[must_use] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
#[cold] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
#[cold] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
#[repr()] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
#[repr()] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
{}

fn another_one() {
// Regression test for https://github.com/rust-lang/rust/issues/143787
let _: String = #[repr()] std::string::String::new();
}
Loading
Loading