Skip to content
Draft
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
25 changes: 18 additions & 7 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns)
| ScopeSet::Module(ns, _)
| ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
ScopeSet::ExternPrelude => (TypeNS, None),
ScopeSet::AttrParent | ScopeSet::ExternPrelude => (TypeNS, None),
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
};
let module = match scope_set {
Expand All @@ -124,6 +124,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let mut scope = match ns {
_ if module_only || module_and_extern_prelude => Scope::ModuleNonGlobs(module, None),
_ if extern_prelude => Scope::ExternPreludeItems,
_ if matches!(scope_set, ScopeSet::AttrParent) => Scope::ToolPrelude,
TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None),
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
};
Expand Down Expand Up @@ -156,7 +157,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {
use_prelude || module_and_extern_prelude || extern_prelude
}
Scope::ToolPrelude => use_prelude,
Scope::ToolPrelude => true,
Scope::StdLibPrelude => use_prelude || ns == MacroNS,
Scope::BuiltinTypes => true,
};
Expand Down Expand Up @@ -222,8 +223,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Scope::BuiltinAttrs => break, // nowhere else to search
Scope::ExternPreludeItems => Scope::ExternPreludeFlags,
Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break,
Scope::ExternPreludeFlags => Scope::ToolPrelude,
Scope::ToolPrelude => Scope::StdLibPrelude,
Scope::ExternPreludeFlags => Scope::StdLibPrelude,
Scope::ToolPrelude => Scope::ModuleNonGlobs(module, None),
Scope::StdLibPrelude => match ns {
TypeNS => Scope::BuiltinTypes,
ValueNS => break, // nowhere else to search
Expand Down Expand Up @@ -424,7 +425,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ScopeSet::All(ns)
| ScopeSet::Module(ns, _)
| ScopeSet::ModuleAndExternPrelude(ns, _) => (ns, None),
ScopeSet::ExternPrelude => (TypeNS, None),
ScopeSet::AttrParent | ScopeSet::ExternPrelude => (TypeNS, None),
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
};
let derive_fallback_lint_id = match finalize {
Expand Down Expand Up @@ -720,7 +721,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None => Err(Determinacy::Determined),
}
}
Scope::ToolPrelude => match self.registered_tool_decls.get(&ident) {
Scope::ToolPrelude => match self.registered_tool_decls.get(&ident.name) {
Some(decl) => Ok(*decl),
None => Err(Determinacy::Determined),
},
Expand Down Expand Up @@ -839,6 +840,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

let ambiguity_error_kind = if is_builtin(innermost_res) || is_builtin(res) {
Some(AmbiguityKind::BuiltinAttr)
} else if matches!(innermost_scope, Scope::ToolPrelude)
|| matches!(scope, Scope::ToolPrelude)
{
Some(AmbiguityKind::ToolAttr)
} else if innermost_res == derive_helper_compat {
Some(AmbiguityKind::DeriveHelper)
} else if res == derive_helper_compat && innermost_res != derive_helper {
Expand Down Expand Up @@ -1947,7 +1952,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} else {
self.reborrow().resolve_ident_in_scope_set(
ident,
ScopeSet::All(ns),
if opt_ns == Some(MacroNS) && !is_last {
// Resolving parent scope for MacroNS (where all attributes belong to, even
// for tool or built-in macros).
ScopeSet::AttrParent
} else {
ScopeSet::All(ns)
},
parent_scope,
finalize,
ignore_decl,
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ enum Scope<'ra> {
#[derive(Clone, Copy, Debug)]
enum ScopeSet<'ra> {
/// All scopes with the given namespace.
///
/// Registered attribute tools are not included; they're available with `AttrParent` only.
All(Namespace),
/// Scopes when resolving for parent scopes for attributes. This is `All` plus registered attribute tools.
AttrParent,
/// Two scopes inside a module, for non-glob and glob bindings.
Module(Namespace, Module<'ra>),
/// A module, then extern prelude (used for mixed 2015-2018 mode in macros).
Expand Down Expand Up @@ -1082,6 +1086,7 @@ struct DelayedVisResolutionError<'ra> {
#[derive(Clone, Copy, PartialEq, Debug)]
enum AmbiguityKind {
BuiltinAttr,
ToolAttr,
DeriveHelper,
MacroRulesVsModularized,
GlobVsOuter,
Expand All @@ -1094,6 +1099,7 @@ impl AmbiguityKind {
fn descr(self) -> &'static str {
match self {
AmbiguityKind::BuiltinAttr => "a name conflict with a builtin attribute",
AmbiguityKind::ToolAttr => "a name conflict with a tool attribute",
AmbiguityKind::DeriveHelper => "a name conflict with a derive helper attribute",
AmbiguityKind::MacroRulesVsModularized => {
"a conflict between a `macro_rules` name and a non-`macro_rules` name from another module"
Expand Down Expand Up @@ -1423,7 +1429,7 @@ pub struct Resolver<'ra, 'tcx> {
dummy_decl: Decl<'ra>,
builtin_type_decls: FxHashMap<Symbol, Decl<'ra>>,
builtin_attr_decls: FxHashMap<Symbol, Decl<'ra>>,
registered_tool_decls: FxHashMap<IdentKey, Decl<'ra>>,
registered_tool_decls: FxHashMap<Symbol, Decl<'ra>>,
macro_names: FxHashSet<IdentKey> = default::fx_hash_set(),
builtin_macros: FxHashMap<Symbol, SyntaxExtensionKind> = default::fx_hash_map(),
registered_tools: &'tcx RegisteredTools,
Expand Down Expand Up @@ -1845,7 +1851,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
.map(|&ident| {
let res = Res::ToolMod;
let decl = arenas.new_pub_def_decl(res, ident.span, LocalExpnId::ROOT);
(IdentKey::new(ident), decl)
(ident.name, decl)
})
.collect(),
registered_tools,
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/diagnostic_namespace/existing_proc_macros.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//@ check-pass
//@ proc-macro: proc-macro-helper.rs

extern crate proc_macro_helper;
Expand All @@ -16,7 +15,7 @@ mod test2 {
pub use proc_macro_helper::diagnostic as on_unimplemented;
}

#[diagnostic::on_unimplemented]
#[diagnostic::on_unimplemented(message = "")] //~ ERROR: ambiguous
trait Foo {}
}

Expand Down
20 changes: 20 additions & 0 deletions tests/ui/diagnostic_namespace/existing_proc_macros.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error[E0659]: `diagnostic` is ambiguous
--> $DIR/existing_proc_macros.rs:18:7
|
LL | #[diagnostic::on_unimplemented(message = "")]
| ^^^^^^^^^^ ambiguous name
|
= note: ambiguous because of a name conflict with a tool attribute
= note: `diagnostic` could refer to a tool module
note: `diagnostic` could also refer to the module defined here
--> $DIR/existing_proc_macros.rs:14:5
|
LL | / mod diagnostic {
LL | | pub use proc_macro_helper::diagnostic as on_unimplemented;
LL | | }
| |_____^
= help: use `self::diagnostic` to refer to this module unambiguously

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0659`.
14 changes: 7 additions & 7 deletions tests/ui/resolve/prelude-order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
Type:
| ...... | tool | extern | macro | lang | libs |
| tool | N/A | mirror
| extern | extern | N/A | universe
| extern | | N/A | universe
| macro | N/A | N/A | N/A |
| lang | tool | extern | N/A | N/A |
| libs | tool | extern | N/A | X | N/A |
| lang | | extern | N/A | N/A |
| libs | | extern | N/A | X | N/A |

Macro:
| ...... | tool | extern | macro | lang | libs |
Expand All @@ -28,7 +28,7 @@ Macro:

Value: N/A. Only libs has items in the value namespace.

† ambiguous
† ambiguous if used as attributes
X don't care (controlled namespace with no overlap)

* Types are tested with `#[name::inner]`. Macros are tested with `#[name]`.
Expand Down Expand Up @@ -59,15 +59,15 @@ extern crate macro_helpers as _;
/* lang and libs implicitly in scope */

// tool/extern -> extern
#[type_ns::inner] //~ ERROR cannot find `inner` in `type_ns`
#[type_ns::inner] //~ ERROR ambiguous
fn t1() {}

// tool/lang -> tool
#[i8::inner] // ok
#[i8::inner] //~ ERROR ambiguous
fn t2() {}

// tool/libs -> tool
#[Sync::not_real] // ok
#[Sync::not_real] //~ ERROR ambiguous
fn t3() {}

// extern/lang -> extern
Expand Down
58 changes: 50 additions & 8 deletions tests/ui/resolve/prelude-order.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
error[E0433]: cannot find `inner` in `type_ns`
--> $DIR/prelude-order.rs:62:12
|
LL | #[type_ns::inner]
| ^^^^^ could not find `inner` in `type_ns`

error[E0433]: cannot find `inner` in `usize`
--> $DIR/prelude-order.rs:74:10
|
Expand All @@ -21,6 +15,54 @@ help: consider importing this enum instead
LL + use std::option::Option;
|

error[E0659]: `type_ns` is ambiguous
--> $DIR/prelude-order.rs:62:3
|
LL | #[type_ns::inner]
| ^^^^^^^ ambiguous name
|
= note: ambiguous because of a name conflict with a tool attribute
note: `type_ns` could refer to the tool module defined here
--> $DIR/prelude-order.rs:46:18
|
LL | #![register_tool(type_ns)] // extern prelude. type.
| ^^^^^^^
note: `type_ns` could also refer to the crate imported here
--> $DIR/prelude-order.rs:51:1
|
LL | extern crate macro_helpers as type_ns; // tool prelude. type.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use `crate::type_ns` to refer to this crate unambiguously

error[E0659]: `i8` is ambiguous
--> $DIR/prelude-order.rs:66:3
|
LL | #[i8::inner]
| ^^ ambiguous name
|
= note: ambiguous because of a name conflict with a tool attribute
= note: `i8` could refer to a builtin type
note: `i8` could also refer to the tool module defined here
--> $DIR/prelude-order.rs:47:18
|
LL | #![register_tool(i8)] // lang prelude. type.
| ^^

error[E0659]: `Sync` is ambiguous
--> $DIR/prelude-order.rs:70:3
|
LL | #[Sync::not_real]
| ^^^^ ambiguous name
|
= note: ambiguous because of a name conflict with a tool attribute
note: `Sync` could refer to the tool module defined here
--> $DIR/prelude-order.rs:48:18
|
LL | #![register_tool(Sync)] // libs prelude. type.
| ^^^^
note: `Sync` could also refer to a trait from prelude
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL

error[E0308]: mismatched types
--> $DIR/prelude-order.rs:83:1
|
Expand All @@ -41,7 +83,7 @@ LL | #[global_allocator]
|
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 5 previous errors
error: aborting due to 7 previous errors

Some errors have detailed explanations: E0308, E0433, E0573.
Some errors have detailed explanations: E0308, E0433, E0573, E0659.
For more information about an error, try `rustc --explain E0308`.
3 changes: 1 addition & 2 deletions tests/ui/resolve/tool-import.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
//@ edition: 2018

use clippy::time::Instant;
//~^ ERROR: cannot find module `clippy`
//~| NOTE: `clippy` is a tool module
//~^ ERROR: cannot find module or crate `clippy`

fn main() {
Instant::now();
Expand Down
6 changes: 4 additions & 2 deletions tests/ui/resolve/tool-import.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0433]: cannot find module `clippy` in this scope
error[E0433]: cannot find module or crate `clippy` in this scope
--> $DIR/tool-import.rs:3:5
|
LL | use clippy::time::Instant;
| ^^^^^^ `clippy` is a tool module, not a module
| ^^^^^^ use of unresolved module or unlinked crate `clippy`
|
= help: you might be missing a crate named `clippy`

error: aborting due to 1 previous error

Expand Down
1 change: 0 additions & 1 deletion tests/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@

pub use ignore as built_in_attr;
pub use u8 as built_in_type;
pub use rustfmt as tool_mod;
2 changes: 0 additions & 2 deletions tests/ui/rust-2018/uniform-paths/cross-crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ extern crate cross_crate;
use cross_crate::*;

#[built_in_attr] //~ ERROR cannot use a built-in attribute through an import
#[tool_mod::skip] //~ ERROR cannot use a tool module through an import
//~| ERROR cannot use a tool module through an import
fn main() {
let _: built_in_type; // OK
}
27 changes: 1 addition & 26 deletions tests/ui/rust-2018/uniform-paths/cross-crate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,5 @@ note: the built-in attribute imported here
LL | use cross_crate::*;
| ^^^^^^^^^^^^^^

error: cannot use a tool module through an import
--> $DIR/cross-crate.rs:8:3
|
LL | #[tool_mod::skip]
| ^^^^^^^^
|
note: the tool module imported here
--> $DIR/cross-crate.rs:5:5
|
LL | use cross_crate::*;
| ^^^^^^^^^^^^^^

error: cannot use a tool module through an import
--> $DIR/cross-crate.rs:8:3
|
LL | #[tool_mod::skip]
| ^^^^^^^^
|
note: the tool module imported here
--> $DIR/cross-crate.rs:5:5
|
LL | use cross_crate::*;
| ^^^^^^^^^^^^^^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 3 previous errors
error: aborting due to 1 previous error

10 changes: 0 additions & 10 deletions tests/ui/rust-2018/uniform-paths/prelude-fail-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,6 @@ mod builtin {
pub use inline as imported_inline;
}

// Tool module
use rustfmt as imported_rustfmt;
mod tool_mod {
pub use rustfmt as imported_rustfmt;
}

#[imported_inline] //~ ERROR cannot use a built-in attribute through an import
#[builtin::imported_inline] //~ ERROR cannot use a built-in attribute through an import
#[imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import
//~| ERROR cannot use a tool module through an import
#[tool_mod::imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import
//~| ERROR cannot use a tool module through an import
fn main() {}
Loading
Loading