Fix ICEs from imports of items not defined in modules
This commit is contained in:
parent
cfd762954b
commit
a38f903114
|
@ -261,6 +261,12 @@ impl NonMacroAttrKind {
|
||||||
|
|
||||||
impl Def {
|
impl Def {
|
||||||
pub fn def_id(&self) -> DefId {
|
pub fn def_id(&self) -> DefId {
|
||||||
|
self.opt_def_id().unwrap_or_else(|| {
|
||||||
|
bug!("attempted .def_id() on invalid def: {:?}", self)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn opt_def_id(&self) -> Option<DefId> {
|
||||||
match *self {
|
match *self {
|
||||||
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
|
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
|
||||||
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) |
|
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) |
|
||||||
|
@ -268,9 +274,8 @@ impl Def {
|
||||||
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
|
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
|
||||||
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
|
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
|
||||||
Def::AssociatedConst(id) | Def::Macro(id, ..) |
|
Def::AssociatedConst(id) | Def::Macro(id, ..) |
|
||||||
Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) |
|
Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) => {
|
||||||
Def::SelfCtor(id) => {
|
Some(id)
|
||||||
id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Def::Local(..) |
|
Def::Local(..) |
|
||||||
|
@ -278,10 +283,11 @@ impl Def {
|
||||||
Def::Label(..) |
|
Def::Label(..) |
|
||||||
Def::PrimTy(..) |
|
Def::PrimTy(..) |
|
||||||
Def::SelfTy(..) |
|
Def::SelfTy(..) |
|
||||||
|
Def::SelfCtor(..) |
|
||||||
Def::ToolMod |
|
Def::ToolMod |
|
||||||
Def::NonMacroAttr(..) |
|
Def::NonMacroAttr(..) |
|
||||||
Def::Err => {
|
Def::Err => {
|
||||||
bug!("attempted .def_id() on invalid def: {:?}", self)
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
self.check_def_id(def.def_id());
|
self.check_def_id(def.def_id());
|
||||||
}
|
}
|
||||||
_ if self.in_pat => (),
|
_ if self.in_pat => (),
|
||||||
Def::PrimTy(..) | Def::SelfTy(..) |
|
Def::PrimTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) |
|
||||||
Def::Local(..) | Def::Upvar(..) => {}
|
Def::Local(..) | Def::Upvar(..) => {}
|
||||||
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
|
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
|
||||||
if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {
|
if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {
|
||||||
|
|
|
@ -781,10 +781,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
||||||
|
|
||||||
fn visit_path(&mut self, path: &'tcx hir::Path, id: hir::HirId) {
|
fn visit_path(&mut self, path: &'tcx hir::Path, id: hir::HirId) {
|
||||||
let id = self.tcx.hir.hir_to_node_id(id);
|
let id = self.tcx.hir.hir_to_node_id(id);
|
||||||
match path.def {
|
if let Some(def_id) = path.def.opt_def_id() {
|
||||||
Def::Local(..) | Def::Upvar(..) | Def::SelfCtor(..) |
|
self.tcx.check_stability(def_id, Some(id), path.span)
|
||||||
Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => {}
|
|
||||||
_ => self.tcx.check_stability(path.def.def_id(), Some(id), path.span)
|
|
||||||
}
|
}
|
||||||
intravisit::walk_path(self, path)
|
intravisit::walk_path(self, path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,9 +361,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
|
||||||
let def_id = self.tcx.hir.local_def_id(id);
|
let def_id = self.tcx.hir.local_def_id(id);
|
||||||
if let Some(exports) = self.tcx.module_exports(def_id) {
|
if let Some(exports) = self.tcx.module_exports(def_id) {
|
||||||
for export in exports.iter() {
|
for export in exports.iter() {
|
||||||
if let Some(node_id) = self.tcx.hir.as_local_node_id(export.def.def_id()) {
|
if export.vis == ty::Visibility::Public {
|
||||||
if export.vis == ty::Visibility::Public {
|
if let Some(def_id) = export.def.opt_def_id() {
|
||||||
self.update(node_id, Some(AccessLevel::Exported));
|
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
|
||||||
|
self.update(node_id, Some(AccessLevel::Exported));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
|
||||||
let binding = self.arenas.alloc_name_binding(NameBinding {
|
let binding = self.arenas.alloc_name_binding(NameBinding {
|
||||||
kind: NameBindingKind::Def(Def::Macro(def_id, kind), false),
|
kind: NameBindingKind::Def(Def::Macro(def_id, kind), false),
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
vis: ty::Visibility::Invisible,
|
vis: ty::Visibility::Public,
|
||||||
expansion: Mark::root(),
|
expansion: Mark::root(),
|
||||||
});
|
});
|
||||||
if self.builtin_macros.insert(ident.name, binding).is_some() {
|
if self.builtin_macros.insert(ident.name, binding).is_some() {
|
||||||
|
|
|
@ -1081,8 +1081,18 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
||||||
// this may resolve to either a value or a type, but for documentation
|
// this may resolve to either a value or a type, but for documentation
|
||||||
// purposes it's good enough to just favor one over the other.
|
// purposes it's good enough to just favor one over the other.
|
||||||
self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
|
self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
|
||||||
|
let mut def = binding.def();
|
||||||
|
if let Def::Macro(def_id, _) = def {
|
||||||
|
// `DefId`s from the "built-in macro crate" should not leak from resolve because
|
||||||
|
// later stages are not ready to deal with them and produce lots of ICEs. Replace
|
||||||
|
// them with `Def::Err` until some saner scheme is implemented for built-in macros.
|
||||||
|
if def_id.krate == CrateNum::BuiltinMacros {
|
||||||
|
this.session.span_err(directive.span, "cannot import a built-in macro");
|
||||||
|
def = Def::Err;
|
||||||
|
}
|
||||||
|
}
|
||||||
let import = this.import_map.entry(directive.id).or_default();
|
let import = this.import_map.entry(directive.id).or_default();
|
||||||
import[ns] = Some(PathResolution::new(binding.def()));
|
import[ns] = Some(PathResolution::new(def));
|
||||||
});
|
});
|
||||||
|
|
||||||
debug!("(resolving single import) successfully resolved import");
|
debug!("(resolving single import) successfully resolved import");
|
||||||
|
@ -1154,9 +1164,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
||||||
if binding.is_import() || binding.is_macro_def() {
|
if binding.is_import() || binding.is_macro_def() {
|
||||||
let def = binding.def();
|
let def = binding.def();
|
||||||
if def != Def::Err {
|
if def != Def::Err {
|
||||||
let def_id = def.def_id();
|
if let Some(def_id) = def.opt_def_id() {
|
||||||
if !def_id.is_local() && def_id.krate != CrateNum::BuiltinMacros {
|
if !def_id.is_local() && def_id.krate != CrateNum::BuiltinMacros {
|
||||||
self.cstore.export_macros_untracked(def_id.krate);
|
self.cstore.export_macros_untracked(def_id.krate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
reexports.push(Export {
|
reexports.push(Export {
|
||||||
ident: ident.modern(),
|
ident: ident.modern(),
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// Tests that arbitrary crates (other than `core`, `std` and `meta`)
|
// Tests that arbitrary crates (other than `core`, `std` and `meta`)
|
||||||
// aren't allowed without `--extern`, even if they're in the sysroot.
|
// aren't allowed without `--extern`, even if they're in the sysroot.
|
||||||
use alloc; //~ ERROR unresolved import `alloc`
|
use alloc; //~ ERROR unresolved import `alloc`
|
||||||
use test; //~ ERROR unresolved import `test`
|
use test; //~ ERROR cannot import a built-in macro
|
||||||
use proc_macro; //~ ERROR unresolved import `proc_macro`
|
use proc_macro; // OK, imports the built-in `proc_macro` attribute, but not the `proc_macro` crate.
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,21 +1,15 @@
|
||||||
|
error: cannot import a built-in macro
|
||||||
|
--> $DIR/not-whitelisted.rs:16:5
|
||||||
|
|
|
||||||
|
LL | use test; //~ ERROR cannot import a built-in macro
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error[E0432]: unresolved import `alloc`
|
error[E0432]: unresolved import `alloc`
|
||||||
--> $DIR/not-whitelisted.rs:15:5
|
--> $DIR/not-whitelisted.rs:15:5
|
||||||
|
|
|
|
||||||
LL | use alloc; //~ ERROR unresolved import `alloc`
|
LL | use alloc; //~ ERROR unresolved import `alloc`
|
||||||
| ^^^^^ no `alloc` external crate
|
| ^^^^^ no `alloc` external crate
|
||||||
|
|
||||||
error[E0432]: unresolved import `test`
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/not-whitelisted.rs:16:5
|
|
||||||
|
|
|
||||||
LL | use test; //~ ERROR unresolved import `test`
|
|
||||||
| ^^^^ no `test` external crate
|
|
||||||
|
|
||||||
error[E0432]: unresolved import `proc_macro`
|
|
||||||
--> $DIR/not-whitelisted.rs:17:5
|
|
||||||
|
|
|
||||||
LL | use proc_macro; //~ ERROR unresolved import `proc_macro`
|
|
||||||
| ^^^^^^^^^^ no `proc_macro` external crate
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0432`.
|
For more information about this error, try `rustc --explain E0432`.
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
// edition:2018
|
||||||
|
|
||||||
|
// For the time being `macro_rules` items are treated as *very* private...
|
||||||
|
|
||||||
|
#![feature(underscore_imports, decl_macro)]
|
||||||
|
|
||||||
|
mod m1 {
|
||||||
|
macro_rules! legacy_macro { () => () }
|
||||||
|
|
||||||
|
// ... so they can't be imported by themselves, ...
|
||||||
|
use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
|
||||||
|
}
|
||||||
|
|
||||||
|
mod m2 {
|
||||||
|
macro_rules! legacy_macro { () => () }
|
||||||
|
|
||||||
|
type legacy_macro = u8;
|
||||||
|
|
||||||
|
// ... but don't prevent names from other namespaces from being imported, ...
|
||||||
|
use legacy_macro as _; // OK
|
||||||
|
}
|
||||||
|
|
||||||
|
mod m3 {
|
||||||
|
macro legacy_macro() {}
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
macro_rules! legacy_macro { () => () }
|
||||||
|
|
||||||
|
// ... but still create ambiguities with other names in the same namespace.
|
||||||
|
use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
|
||||||
|
//~| ERROR `legacy_macro` is private, and cannot be re-exported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod exported {
|
||||||
|
// Exported macros are treated as private as well,
|
||||||
|
// some better rules need to be figured out later.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! legacy_macro { () => () }
|
||||||
|
|
||||||
|
use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,58 @@
|
||||||
|
error[E0364]: `legacy_macro` is private, and cannot be re-exported
|
||||||
|
--> $DIR/macro-rules.rs:11:9
|
||||||
|
|
|
||||||
|
LL | use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: consider marking `legacy_macro` as `pub` in the imported module
|
||||||
|
--> $DIR/macro-rules.rs:11:9
|
||||||
|
|
|
||||||
|
LL | use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0364]: `legacy_macro` is private, and cannot be re-exported
|
||||||
|
--> $DIR/macro-rules.rs:30:13
|
||||||
|
|
|
||||||
|
LL | use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: consider marking `legacy_macro` as `pub` in the imported module
|
||||||
|
--> $DIR/macro-rules.rs:30:13
|
||||||
|
|
|
||||||
|
LL | use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0364]: `legacy_macro` is private, and cannot be re-exported
|
||||||
|
--> $DIR/macro-rules.rs:41:9
|
||||||
|
|
|
||||||
|
LL | use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: consider marking `legacy_macro` as `pub` in the imported module
|
||||||
|
--> $DIR/macro-rules.rs:41:9
|
||||||
|
|
|
||||||
|
LL | use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0659]: `legacy_macro` is ambiguous (name vs any other name during import resolution)
|
||||||
|
--> $DIR/macro-rules.rs:30:13
|
||||||
|
|
|
||||||
|
LL | use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
|
||||||
|
| ^^^^^^^^^^^^ ambiguous name
|
||||||
|
|
|
||||||
|
note: `legacy_macro` could refer to the macro defined here
|
||||||
|
--> $DIR/macro-rules.rs:27:9
|
||||||
|
|
|
||||||
|
LL | macro_rules! legacy_macro { () => () }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: `legacy_macro` could also refer to the macro defined here
|
||||||
|
--> $DIR/macro-rules.rs:24:5
|
||||||
|
|
|
||||||
|
LL | macro legacy_macro() {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= help: use `self::legacy_macro` to refer to this macro unambiguously
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
Some errors occurred: E0364, E0659.
|
||||||
|
For more information about an error, try `rustc --explain E0364`.
|
|
@ -0,0 +1,11 @@
|
||||||
|
// edition:2018
|
||||||
|
|
||||||
|
// Built-in macro
|
||||||
|
use env as env_imported; //~ ERROR cannot import a built-in macro
|
||||||
|
|
||||||
|
// Tool attribute
|
||||||
|
use rustfmt::skip as imported_rustfmt_skip; //~ ERROR unresolved import `rustfmt`
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
env_imported!("PATH");
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
error: cannot import a built-in macro
|
||||||
|
--> $DIR/prelude-fail.rs:4:5
|
||||||
|
|
|
||||||
|
LL | use env as env_imported; //~ ERROR cannot import a built-in macro
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0432]: unresolved import `rustfmt`
|
||||||
|
--> $DIR/prelude-fail.rs:7:5
|
||||||
|
|
|
||||||
|
LL | use rustfmt::skip as imported_rustfmt_skip; //~ ERROR unresolved import `rustfmt`
|
||||||
|
| ^^^^^^^ Not a module `rustfmt`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0432`.
|
|
@ -0,0 +1,26 @@
|
||||||
|
// compile-pass
|
||||||
|
// edition:2018
|
||||||
|
|
||||||
|
// Macro imported with `#[macro_use] extern crate`
|
||||||
|
use vec as imported_vec;
|
||||||
|
|
||||||
|
// Built-in attribute
|
||||||
|
use inline as imported_inline;
|
||||||
|
|
||||||
|
// Tool module
|
||||||
|
use rustfmt as imported_rustfmt;
|
||||||
|
|
||||||
|
// Standard library prelude
|
||||||
|
use Vec as ImportedVec;
|
||||||
|
|
||||||
|
// Built-in type
|
||||||
|
use u8 as imported_u8;
|
||||||
|
|
||||||
|
type A = imported_u8;
|
||||||
|
|
||||||
|
#[imported_inline]
|
||||||
|
#[imported_rustfmt::skip]
|
||||||
|
fn main() {
|
||||||
|
imported_vec![0];
|
||||||
|
ImportedVec::<u8>::new();
|
||||||
|
}
|
Loading…
Reference in New Issue