-
Notifications
You must be signed in to change notification settings - Fork 13.8k
add transparent attribute for mod items #147709
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
use super::prelude::*; | ||
|
||
pub(crate) struct TransparentParser; | ||
impl<S: Stage> NoArgsAttributeParser<S> for TransparentParser { | ||
const PATH: &[Symbol] = &[sym::transparent]; | ||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; | ||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]); | ||
const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::Transparent(span); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -237,6 +237,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | |
return Some((module.parent.unwrap().nearest_item_scope(), None)); | ||
} | ||
|
||
if module.is_transparent() { | ||
return Some((module.parent.unwrap().nearest_item_scope(), None)); | ||
} | ||
|
||
// We need to support the next case under a deprecation warning | ||
// ``` | ||
// struct MyStruct; | ||
|
@@ -250,12 +254,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | |
// So we have to fall back to the module's parent during lexical resolution in this case. | ||
if derive_fallback_lint_id.is_some() | ||
&& let Some(parent) = module.parent | ||
// Inner module is inside the macro | ||
&& module.expansion != parent.expansion | ||
// Parent module is outside of the macro | ||
&& module.expansion.is_descendant_of(parent.expansion) | ||
// The macro is a proc macro derive | ||
&& let Some(def_id) = module.expansion.expn_data().macro_def_id | ||
// Inner module is inside the macro | ||
&& module.expansion != parent.expansion | ||
// Parent module is outside of the macro | ||
&& module.expansion.is_descendant_of(parent.expansion) | ||
// The macro is a proc macro derive | ||
&& let Some(def_id) = module.expansion.expn_data().macro_def_id | ||
Comment on lines
+257
to
+262
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ill clean this up in the next pass, formatting got fked up in a few places >:[ |
||
{ | ||
let ext = &self.get_macro_by_def_id(def_id).ext; | ||
if ext.builtin_name.is_none() | ||
|
@@ -345,7 +349,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | |
// Encountered a module item, abandon ribs and look into that module and preludes. | ||
let parent_scope = &ParentScope { module, ..*parent_scope }; | ||
let finalize = finalize.map(|f| Finalize { stage: Stage::Late, ..f }); | ||
return self | ||
let binding = self | ||
.cm() | ||
.resolve_ident_in_scope_set( | ||
orig_ident, | ||
|
@@ -356,8 +360,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | |
ignore_binding, | ||
None, | ||
) | ||
.ok() | ||
.map(LexicalScopeBinding::Item); | ||
.ok(); | ||
match binding { | ||
Some(binding) => { | ||
return Some(LexicalScopeBinding::Item(binding)); | ||
} | ||
None => { | ||
if !module.is_transparent() { | ||
return None; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if let RibKind::MacroDefinition(def) = rib.kind | ||
|
@@ -690,7 +703,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | |
span_bug!( | ||
orig_ident.span, | ||
"ambiguous scoped macro resolutions with path-based \ | ||
scope resolution as first candidate" | ||
scope resolution as first candidate" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: cleanup formatting |
||
) | ||
} else if innermost_binding.is_glob_import() { | ||
Some(AmbiguityKind::GlobVsOuter) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -524,17 +524,19 @@ enum ModuleKind { | |
/// * A normal module – either `mod from_file;` or `mod from_block { }` – | ||
/// or the crate root (which is conceptually a top-level module). | ||
/// The crate root will have `None` for the symbol. | ||
/// * the bool in the tuple next to symbol represents whether the "transparent" | ||
/// attribute is present on the module, only applies to named `mod` items. | ||
/// * A trait or an enum (it implicitly contains associated types, methods and variant | ||
/// constructors). | ||
Def(DefKind, DefId, Option<Symbol>), | ||
Def(DefKind, DefId, Option<(Symbol, bool)>), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was the most obvious place to put this but it doesn't feel great, don't love all the places where I changed shit to |
||
} | ||
|
||
impl ModuleKind { | ||
/// Get name of the module. | ||
fn name(&self) -> Option<Symbol> { | ||
match *self { | ||
ModuleKind::Block => None, | ||
ModuleKind::Def(.., name) => name, | ||
ModuleKind::Def(.., name_and_transparent) => name_and_transparent.map(|(name, _)| name), | ||
} | ||
} | ||
} | ||
|
@@ -759,6 +761,13 @@ impl<'ra> Module<'ra> { | |
} | ||
} | ||
|
||
fn is_transparent(self) -> bool { | ||
match self.kind { | ||
ModuleKind::Def(DefKind::Mod, _, Some((_, transparent))) => transparent, | ||
_ => false, | ||
} | ||
} | ||
|
||
fn is_ancestor_of(self, mut other: Self) -> bool { | ||
while self != other { | ||
if let Some(parent) = other.parent { | ||
|
@@ -2449,7 +2458,7 @@ fn module_to_string(mut module: Module<'_>) -> Option<String> { | |
if let ModuleKind::Def(.., name) = module.kind { | ||
if let Some(parent) = module.parent { | ||
// `unwrap` is safe: the presence of a parent means it's not the crate root. | ||
names.push(name.unwrap()); | ||
names.push(name.unwrap().0); | ||
module = parent | ||
} else { | ||
break; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2230,6 +2230,7 @@ symbols! { | |
transmute_unchecked, | ||
transparent, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like I'm probably doing this part subtly wrong. The transparent symbol already exists and I'm using it, I tried seeing if I could stay away from it and find a way to have all the compiler internal stuff talk about it with a unique symbol ( |
||
transparent_enums, | ||
transparent_modules, | ||
transparent_unions, | ||
trivial_bounds, | ||
truncf16, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//@ check-fail | ||
//@ edition:2018 | ||
mod y { | ||
macro_rules! s { | ||
() => {}; | ||
} | ||
|
||
pub(crate) use s; | ||
} | ||
|
||
fn foo() { | ||
struct S; | ||
use y::s; | ||
mod x { | ||
// early resolution | ||
s!(); //~ ERROR cannot find macro `s` in this scope | ||
// late resolution | ||
struct Y(S); //~ ERROR cannot find type `S` in this scope | ||
} | ||
} | ||
|
||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
error: cannot find macro `s` in this scope | ||
--> $DIR/transparent-fail.rs:16:9 | ||
| | ||
LL | s!(); | ||
| ^ | ||
| | ||
= help: have you added the `#[macro_use]` on the module/import? | ||
help: consider importing this macro through its public re-export | ||
| | ||
LL + use crate::y::s; | ||
| | ||
|
||
error[E0412]: cannot find type `S` in this scope | ||
--> $DIR/transparent-fail.rs:18:18 | ||
| | ||
LL | struct Y(S); | ||
| ^ not found in this scope | ||
| | ||
help: you might be missing a type parameter | ||
| | ||
LL | struct Y<S>(S); | ||
| +++ | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0412`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//@ check-pass | ||
//@ edition:2018 | ||
#![feature(transparent_modules)] | ||
|
||
mod y { | ||
macro_rules! s { | ||
() => {}; | ||
} | ||
|
||
pub(crate) use s; | ||
} | ||
|
||
fn foo() { | ||
struct S; | ||
use y::s; | ||
#[transparent] | ||
mod x { | ||
// early resolution | ||
s!(); | ||
// late resolution | ||
struct Y(S); | ||
} | ||
} | ||
|
||
pub fn main() { | ||
foo(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for a closure here