Skip to content
Open
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
11 changes: 11 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/stability.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::num::NonZero;

use rustc_errors::ErrorGuaranteed;
use rustc_feature::ACCEPTED_LANG_FEATURES;
use rustc_hir::target::GenericParamKind;
use rustc_hir::{
DefaultBodyStability, MethodKind, PartialConstStability, Stability, StabilityLevel,
Expand Down Expand Up @@ -465,6 +466,16 @@ pub(crate) fn parse_unstability<S: Stage>(

match (feature, issue) {
(Ok(feature), Ok(_)) => {
// Stable *language* features shouldn't be used as unstable library features.
// (Not doing this for stable library features is checked by tidy.)
if ACCEPTED_LANG_FEATURES.iter().any(|f| f.name == feature) {
cx.emit_err(session_diagnostics::UnstableAttrForAlreadyStableFeature {
attr_span: cx.attr_span,
item_span: cx.target_span,
});
return None;
}

let level = StabilityLevel::Unstable {
reason: UnstableReason::from_opt_reason(reason),
issue: issue_num,
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1030,3 +1030,14 @@ pub(crate) struct UnsupportedInstructionSet<'a> {
pub instruction_set: Symbol,
pub current_target: &'a TargetTuple,
}

#[derive(Diagnostic)]
#[diag("can't mark as unstable using an already stable feature")]
pub(crate) struct UnstableAttrForAlreadyStableFeature {
#[primary_span]
#[label("this feature is already stable")]
#[help("consider removing the attribute")]
pub attr_span: Span,
#[label("the stability attribute annotates this item")]
pub item_span: Span,
}
38 changes: 5 additions & 33 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_data_structures::unord::UnordMap;
use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey, msg};
use rustc_feature::{
ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP,
BuiltinAttribute,
};
use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
use rustc_hir::attrs::diagnostic::Directive;
use rustc_hir::attrs::{
AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, InlineAttr,
Expand All @@ -30,8 +27,7 @@ use rustc_hir::def_id::LocalModDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{
self as hir, Attribute, CRATE_HIR_ID, Constness, FnSig, ForeignItem, GenericParamKind, HirId,
Item, ItemKind, MethodKind, Node, ParamName, PartialConstStability, Safety, Stability,
StabilityLevel, Target, TraitItem, find_attr,
Item, ItemKind, MethodKind, Node, ParamName, Safety, Target, TraitItem, find_attr,
};
use rustc_macros::Diagnostic;
use rustc_middle::hir::nested_filter;
Expand Down Expand Up @@ -153,15 +149,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.check_proc_macro(hir_id, target, ProcMacroKind::Derive)
}
Attribute::Parsed(
AttributeKind::Stability {
span: attr_span,
stability: Stability { level, feature },
}
| AttributeKind::RustcConstStability {
span: attr_span,
stability: PartialConstStability { level, feature, .. },
},
) => self.check_stability(*attr_span, span, level, *feature),
AttributeKind::Stability { .. }
| AttributeKind::RustcConstStability { .. },
) => {}
Attribute::Parsed(AttributeKind::Inline(InlineAttr::Force { .. }, ..)) => {} // handled separately below
Attribute::Parsed(AttributeKind::Inline(kind, attr_span)) => {
self.check_inline(hir_id, *attr_span, kind, target)
Expand Down Expand Up @@ -1515,24 +1505,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}

fn check_stability(
&self,
attr_span: Span,
item_span: Span,
level: &StabilityLevel,
feature: Symbol,
) {
// Stable *language* features shouldn't be used as unstable library features.
// (Not doing this for stable library features is checked by tidy.)
if level.is_unstable()
&& ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some()
{
self.tcx
.dcx()
.emit_err(errors::UnstableAttrForAlreadyStableFeature { attr_span, item_span });
}
}

fn check_deprecated(&self, hir_id: HirId, attr_span: Span, target: Target) {
match target {
Target::AssocConst | Target::Method(..) | Target::AssocTy
Expand Down
11 changes: 0 additions & 11 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,17 +872,6 @@ pub(crate) struct CannotStabilizeDeprecated {
pub item_sp: Span,
}

#[derive(Diagnostic)]
#[diag("can't mark as unstable using an already stable feature")]
pub(crate) struct UnstableAttrForAlreadyStableFeature {
#[primary_span]
#[label("this feature is already stable")]
#[help("consider removing the attribute")]
pub attr_span: Span,
#[label("the stability attribute annotates this item")]
pub item_span: Span,
}

#[derive(Diagnostic)]
#[diag("{$descr} has missing stability attribute")]
pub(crate) struct MissingStabilityAttr<'a> {
Expand Down
Loading