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
27 changes: 26 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ use rustc_feature::AttributeStability;
use rustc_hir::LangItem;
use rustc_hir::attrs::{
BorrowckGraphvizFormatKind, CguFields, CguKind, DivergingBlockBehavior,
DivergingFallbackBehavior, RustcCleanAttribute, RustcCleanQueries, RustcMirKind,
DivergingFallbackBehavior, EditionRedirect, RustcCleanAttribute, RustcCleanQueries,
RustcMirKind,
};
use rustc_hir::target::GenericParamKind;
use rustc_span::Symbol;
use rustc_span::edition::Edition;

use super::prelude::*;
use super::util::parse_single_integer;
Expand Down Expand Up @@ -342,6 +344,29 @@ impl AttributeParser for RustcCguTestAttributeParser {
}
}

pub(crate) struct RustcEditionRedirectParser;

impl SingleAttributeParser for RustcEditionRedirectParser {
const PATH: &[Symbol] = &[sym::rustc_edition_redirect];
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Use)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "2024");
const STABILITY: AttributeStability = unstable!(edition_redirect);

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
let value = cx.expect_name_value(args, cx.attr_span, Some(sym::rustc_edition_redirect))?;
let value = cx.expect_string_literal(value)?;
let before = match value.as_str().parse::<Edition>() {
Ok(before) => before,
Err(()) => {
cx.emit_err(diagnostics::InvalidEditionRedirect { span: cx.attr_span });
return None;
}
};

Some(AttributeKind::RustcEditionRedirect(EditionRedirect { before, span: cx.attr_span }))
}
}

pub(crate) struct RustcDeprecatedSafe2024Parser;

impl SingleAttributeParser for RustcDeprecatedSafe2024Parser {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ attribute_parsers!(
Single<RustcDummyParser>,
Single<RustcDumpDefPathParser>,
Single<RustcDumpSymbolNameParser>,
Single<RustcEditionRedirectParser>,
Single<RustcForceInlineParser>,
Single<RustcIfThisChangedParser>,
Single<RustcLegacyConstGenericsParser>,
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_attr_parsing/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ pub(crate) struct ItemFollowingInnerAttr {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("invalid edition in edition redirect")]
pub(crate) struct InvalidEditionRedirect {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("unreachable configuration predicate")]
pub(crate) struct UnreachableCfgSelectPredicate {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[
sym::rustc_eii_foreign_item,
sym::rustc_allowed_through_unstable_modules,
sym::rustc_deprecated_safe_2024,
sym::rustc_edition_redirect,
sym::rustc_pub_transparent,

// ==========================================================================
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ declare_features! (
(internal, const_param_ty_unchecked, "1.97.0", None),
/// Allows writing custom MIR
(internal, custom_mir, "1.65.0", None),
/// Allows defining edition redirects and preserving redirects on re-exports.
(internal, edition_redirect, "CURRENT_RUSTC_VERSION", None),
/// Implementation details of externally implementable items
(internal, eii_internals, "1.94.0", None),
/// Implementation details of field representing types.
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
use rustc_macros::{Decodable, Encodable, PrintAttribute, StableHash};
use rustc_span::def_id::DefId;
use rustc_span::edition::Edition;
use rustc_span::hygiene::Transparency;
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
pub use rustc_target::spec::SanitizerSet;
Expand Down Expand Up @@ -152,6 +153,12 @@ pub enum InstrumentFnAttr {
Off,
}

#[derive(Clone, Copy, Debug, StableHash, Encodable, Decodable, PrintAttribute)]
pub struct EditionRedirect {
pub before: Edition,
pub span: Span,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Default, PrintAttribute)]
#[derive(Encodable, Decodable, StableHash)]
pub enum OptimizeAttr {
Expand Down Expand Up @@ -1480,6 +1487,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_dyn_incompatible_trait]`.
RustcDynIncompatibleTrait(Span),

/// Represents `#[rustc_edition_redirect = "..."]`.
RustcEditionRedirect(EditionRedirect),

/// Represents `#[rustc_effective_visibility]`.
RustcEffectiveVisibility,

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ impl AttributeKind {
RustcDumpVariancesOfOpaques => No,
RustcDumpVtable(..) => No,
RustcDynIncompatibleTrait(..) => No,
RustcEditionRedirect(..) => No,
RustcEffectiveVisibility => Yes,
RustcEiiForeignItem => No,
RustcEvaluateWhereClauses => Yes,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir/src/attrs/pretty_printing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc_ast_pretty::pp::Printer;
use rustc_data_structures::Limit;
use rustc_data_structures::fx::FxIndexMap;
use rustc_span::def_id::DefId;
use rustc_span::edition::Edition;
use rustc_span::hygiene::Transparency;
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol};
use rustc_target::spec::SanitizerSet;
Expand Down Expand Up @@ -191,7 +192,7 @@ macro_rules! print_tup {

print_tup!(A B C D E F G H);
print_skip!(Span, (), ErrorGuaranteed, AttrId);
print_disp!(u8, u16, u32, u128, usize, bool, NonZero<u32>, Limit);
print_disp!(u8, u16, u32, u128, usize, bool, NonZero<u32>, Edition, Limit);
print_debug!(
Symbol,
Ident,
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1313,7 +1313,14 @@ impl CrateMetadata {
let res = Res::Def(self.def_kind(id), self.local_def_id(id));
let vis = self.get_visibility(tcx, id);

ModChild { ident, res, vis, reexport_chain: Default::default() }
ModChild {
ident,
res,
vis,
reexport_chain: Default::default(),
// Children with redirects are encoded as full `ModChild`s.
edition_redirects: Default::default(),
}
}

/// Iterates over all named children of the given module,
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1736,11 +1736,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let module_children = tcx.module_children_local(local_def_id);

record_array!(self.tables.module_children_non_reexports[def_id] <-
module_children.iter().filter(|child| child.reexport_chain.is_empty())
module_children.iter().filter(|child| child.reexport_chain.is_empty()
&& child.edition_redirects.is_empty())
.map(|child| child.res.def_id().index));

record_defaulted_array!(self.tables.module_children_reexports[def_id] <-
module_children.iter().filter(|child| !child.reexport_chain.is_empty()));
module_children.iter().filter(|child| !child.reexport_chain.is_empty()
|| !child.edition_redirects.is_empty()));

let ambig_module_children = tcx
.resolutions(())
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,10 +402,9 @@ define_tables! {
explicit_implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
// Reexported names are not associated with individual `DefId`s,
// e.g. a glob import can introduce a lot of names, all with the same `DefId`.
// That's why the encoded list needs to contain `ModChild` structures describing all the names
// individually instead of `DefId`s.
// Names requiring data beyond the item's own `DefId` are encoded as full `ModChild`s.
// This includes reexports, where a glob can introduce many names with the same `DefId`, and
// proper items carrying edition redirects.
module_children_reexports: Table<DefIndex, LazyArray<ModChild>>,
ambig_module_children: Table<DefIndex, LazyArray<AmbigModChild>>,
cross_crate_inlinable: Table<DefIndex, bool>,
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_middle/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use rustc_hir::def::Res;
use rustc_macros::{StableHash, TyDecodable, TyEncodable};
use rustc_span::Ident;
use rustc_span::def_id::{DefId, ModId};
use rustc_span::edition::Edition;
use smallvec::SmallVec;

use crate::ty;
Expand All @@ -26,6 +27,13 @@ impl Reexport {
}
}

/// A different item that a module child resolves to before an edition boundary.
#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, StableHash)]
pub struct EditionRedirect {
pub before: Edition,
pub target: Res<!>,
}

/// This structure is supposed to keep enough data to re-create `Decl`s for other crates
/// during name resolution. Right now the bindings are not recreated entirely precisely so we may
/// need to add more data in the future to correctly support macros 2.0, for example.
Expand All @@ -43,6 +51,8 @@ pub struct ModChild {
/// Reexport chain linking this module child to its original reexported item.
/// Empty if the module child is a proper item.
pub reexport_chain: SmallVec<[Reexport; 2]>,
/// Edition-dependent alternatives, sorted from the earliest boundary to the latest.
pub edition_redirects: SmallVec<[EditionRedirect; 1]>,
}

/// Same as `ModChild`, however, it includes ambiguity error.
Expand Down
18 changes: 16 additions & 2 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, msg};
use rustc_feature::BUILTIN_ATTRIBUTE_MAP;
use rustc_hir::attrs::diagnostic::Directive;
use rustc_hir::attrs::{
AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, InlineAttr,
OptimizeAttr, ReprAttr,
AttributeKind, DocAttribute, DocInline, EditionRedirect, EiiDecl, EiiImpl, EiiImplResolution,
InlineAttr, OptimizeAttr, ReprAttr,
};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalModId;
Expand Down Expand Up @@ -229,6 +229,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
AttributeKind::Linkage(_linkage, span) => {
self.check_linkage(*span, hir_id, target, item)
}
AttributeKind::RustcEditionRedirect(redirect) => {
self.check_rustc_edition_redirect(item, redirect)
}

// All of the following attributes have no specific checks.
// tidy-alphabetical-start
Expand Down Expand Up @@ -411,6 +414,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}

/// Rejects the use of edition redirect on non-single use statements.
fn check_rustc_edition_redirect(&self, item: Option<&Item<'_>>, redirect: &EditionRedirect) {
let Some(Item { kind: ItemKind::Use(_, use_kind), .. }) = item else {
return;
};
if matches!(use_kind, hir::UseKind::Single(_)) {
return;
}
self.dcx().emit_err(diagnostics::EditionRedirectNonSingleUse { attr_span: redirect.span });
}

fn check_rustc_must_implement_one_of(
&self,
attr_span: Span,
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_passes/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ use rustc_span::{DUMMY_SP, Ident, Span, Symbol};
use crate::check_attr::ProcMacroKind;
use crate::lang_items::Duplicate;

#[derive(Diagnostic)]
#[diag("`#[rustc_edition_redirect]` can only be applied to a single import")]
#[help("use a separate, non-braced `use` item")]
pub(crate) struct EditionRedirectNonSingleUse {
#[primary_span]
pub attr_span: Span,
}

#[derive(Diagnostic)]
#[diag("`{$no_mangle_attr}` attribute may not be used in combination with `{$export_name_attr}`")]
pub(crate) struct MixedExportNameAndNoMangle {
Expand Down
Loading
Loading