Skip to content

Commit 25ccaa9

Browse files
committed
add transparent attribute for mod items
1 parent 4742769 commit 25ccaa9

18 files changed

Lines changed: 306 additions & 15 deletions

File tree

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub(crate) mod link_attrs;
4848
pub(crate) mod lint_helpers;
4949
pub(crate) mod loop_match;
5050
pub(crate) mod macro_attrs;
51+
pub(crate) mod modules;
5152
pub(crate) mod must_not_suspend;
5253
pub(crate) mod must_use;
5354
pub(crate) mod no_implicit_prelude;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use super::prelude::*;
2+
3+
pub(crate) struct TransparentParser;
4+
impl<S: Stage> NoArgsAttributeParser<S> for TransparentParser {
5+
const PATH: &[Symbol] = &[sym::transparent];
6+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
7+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]);
8+
const CREATE: fn(Span) -> AttributeKind = AttributeKind::Transparent;
9+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use crate::attributes::macro_attrs::{
5454
AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser,
5555
MacroUseParser,
5656
};
57+
use crate::attributes::modules::TransparentParser;
5758
use crate::attributes::must_not_suspend::MustNotSuspendParser;
5859
use crate::attributes::must_use::MustUseParser;
5960
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
@@ -315,6 +316,7 @@ attribute_parsers!(
315316
Single<WithoutArgs<StdInternalSymbolParser>>,
316317
Single<WithoutArgs<ThreadLocalParser>>,
317318
Single<WithoutArgs<TrackCallerParser>>,
319+
Single<WithoutArgs<TransparentParser>>,
318320
Single<WithoutArgs<TypeConstParser>>,
319321
Single<WithoutArgs<UnsafeSpecializationMarkerParser>>,
320322
// tidy-alphabetical-end

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,12 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
917917
EncodeCrossCrate::Yes, pin_ergonomics, experimental!(pin_v2),
918918
),
919919

920+
gated!(
921+
transparent, Normal,
922+
template!(Word, "https://github.com/rust-lang/rust/issues/79260#issuecomment-731773625"),
923+
ErrorFollowing, EncodeCrossCrate::No, transparent_modules, experimental!(transparent)
924+
),
925+
920926
// ==========================================================================
921927
// Internal attributes: Stability, deprecation, and unsafe:
922928
// ==========================================================================

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,8 @@ declare_features! (
664664
(unstable, trait_alias, "1.24.0", Some(41517)),
665665
/// Allows for transmuting between arrays with sizes that contain generic consts.
666666
(unstable, transmute_generic_consts, "1.70.0", Some(109929)),
667+
/// Allows #[transparent] on modules to inherit lexical scopes.
668+
(unstable, transparent_modules, "1.91.0", Some(79260)),
667669
/// Allows #[repr(transparent)] on unions (RFC 2645).
668670
(unstable, transparent_unions, "1.37.0", Some(60405)),
669671
/// Allows inconsistent bounds in where clauses.

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,9 @@ pub enum AttributeKind {
11771177
/// Represents `#[track_caller]`
11781178
TrackCaller(Span),
11791179

1180+
/// Represents `#[transparent]` mod attribute
1181+
Transparent(Span),
1182+
11801183
/// Represents `#[type_const]`.
11811184
TypeConst(Span),
11821185

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ impl AttributeKind {
147147
TargetFeature { .. } => No,
148148
ThreadLocal => No,
149149
TrackCaller(..) => Yes,
150+
Transparent(..) => No,
150151
TypeConst(..) => Yes,
151152
TypeLengthLimit { .. } => No,
152153
UnsafeSpecializationMarker(..) => No,

compiler/rustc_passes/src/check_attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
233233
| AttributeKind::CfgAttrTrace
234234
| AttributeKind::CfgTrace(..)
235235
| AttributeKind::CfiEncoding { .. }
236+
| AttributeKind::Transparent(_)
236237
| AttributeKind::Coinductive(..)
237238
| AttributeKind::Cold(..)
238239
| AttributeKind::CollapseDebugInfo(..)

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
164164
let expn_id = self.cstore().expn_that_defined_untracked(self.tcx, def_id);
165165
return Some(self.new_extern_module(
166166
parent,
167-
ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))),
167+
ModuleKind::Def(
168+
def_kind,
169+
def_id,
170+
Some((self.tcx.item_name(def_id), false)),
171+
),
168172
expn_id,
169173
self.def_span(def_id),
170174
// FIXME: Account for `#[no_implicit_prelude]` attributes.
@@ -665,14 +669,14 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
665669
// Disallow `use $crate;`
666670
if source.ident.name == kw::DollarCrate && module_path.is_empty() {
667671
let crate_root = self.r.resolve_crate_root(source.ident);
668-
let crate_name = match crate_root.kind {
669-
ModuleKind::Def(.., name) => name,
672+
let crate_name_and_transparent = match crate_root.kind {
673+
ModuleKind::Def(.., name_and_transparent) => name_and_transparent,
670674
ModuleKind::Block => unreachable!(),
671675
};
672676
// HACK(eddyb) unclear how good this is, but keeping `$crate`
673677
// in `source` breaks `tests/ui/imports/import-crate-var.rs`,
674678
// while the current crate doesn't have a valid `crate_name`.
675-
if let Some(crate_name) = crate_name {
679+
if let Some((crate_name, _transparent)) = crate_name_and_transparent {
676680
// `crate_name` should not be interpreted as relative.
677681
module_path.push(Segment::from_ident_and_id(
678682
Ident::new(kw::PathRoot, source.ident.span),
@@ -853,9 +857,18 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
853857
{
854858
self.r.mods_with_parse_errors.insert(def_id);
855859
}
860+
let transparent = AttributeParser::parse_limited(
861+
self.r.tcx.sess,
862+
&item.attrs,
863+
sym::transparent,
864+
item.span,
865+
item.id,
866+
None,
867+
)
868+
.is_some();
856869
self.parent_scope.module = self.r.new_local_module(
857870
Some(parent),
858-
ModuleKind::Def(def_kind, def_id, Some(ident.name)),
871+
ModuleKind::Def(def_kind, def_id, Some((ident.name, transparent))),
859872
expansion.to_expn_id(),
860873
item.span,
861874
parent.no_implicit_prelude
@@ -888,7 +901,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
888901

889902
self.parent_scope.module = self.r.new_local_module(
890903
Some(parent),
891-
ModuleKind::Def(def_kind, def_id, Some(ident.name)),
904+
ModuleKind::Def(def_kind, def_id, Some((ident.name, false))),
892905
expansion.to_expn_id(),
893906
item.span,
894907
parent.no_implicit_prelude,

compiler/rustc_resolve/src/ident.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
252252
return Some((module.parent.unwrap().nearest_item_scope(), None));
253253
}
254254

255+
if module.is_transparent() {
256+
return Some((module.parent.unwrap().nearest_item_scope(), None));
257+
}
258+
255259
// We need to support the next case under a deprecation warning
256260
// ```
257261
// struct MyStruct;
@@ -360,7 +364,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
360364
// Encountered a module item, abandon ribs and look into that module and preludes.
361365
let parent_scope = &ParentScope { module, ..*parent_scope };
362366
let finalize = finalize.map(|f| Finalize { stage: Stage::Late, ..f });
363-
return self
367+
let binding = self
364368
.cm()
365369
.resolve_ident_in_scope_set(
366370
orig_ident,
@@ -371,8 +375,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
371375
ignore_decl,
372376
None,
373377
)
374-
.ok()
375-
.map(LateDecl::Decl);
378+
.ok();
379+
match binding {
380+
Some(binding) => {
381+
return Some(LateDecl::Decl(binding));
382+
}
383+
None => {
384+
if !module.is_transparent() {
385+
return None;
386+
}
387+
}
388+
}
376389
}
377390

378391
if let RibKind::MacroDefinition(def) = rib.kind

0 commit comments

Comments
 (0)