Skip to content

Commit 17f510b

Browse files
committed
Rollup merge of #57483 - petrochenkov:beta, r=pietroalbini
2 parents b9f08d2 + bc232d3 commit 17f510b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+299
-337
lines changed

src/librustc/hir/def.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ impl CtorKind {
248248
}
249249

250250
impl NonMacroAttrKind {
251-
fn descr(self) -> &'static str {
251+
pub fn descr(self) -> &'static str {
252252
match self {
253253
NonMacroAttrKind::Builtin => "built-in attribute",
254254
NonMacroAttrKind::Tool => "tool attribute",

src/librustc_resolve/build_reduced_graph.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
230230
}
231231

232232
let subclass = SingleImport {
233-
target: ident,
234233
source: source.ident,
235-
result: PerNS {
234+
target: ident,
235+
source_bindings: PerNS {
236236
type_ns: Cell::new(Err(Undetermined)),
237237
value_ns: Cell::new(Err(Undetermined)),
238238
macro_ns: Cell::new(Err(Undetermined)),
239239
},
240+
target_bindings: PerNS {
241+
type_ns: Cell::new(None),
242+
value_ns: Cell::new(None),
243+
macro_ns: Cell::new(None),
244+
},
240245
type_ns_only,
241246
};
242247
self.add_import_directive(

src/librustc_resolve/lib.rs

+30-5
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
7575
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
7676

7777
use std::cell::{Cell, RefCell};
78-
use std::{cmp, fmt, iter, ptr};
78+
use std::{cmp, fmt, iter, mem, ptr};
7979
use std::collections::BTreeSet;
8080
use std::mem::replace;
8181
use rustc_data_structures::ptr_key::PtrKey;
@@ -1521,6 +1521,7 @@ pub struct Resolver<'a, 'b: 'a> {
15211521

15221522
/// FIXME: Refactor things so that this is passed through arguments and not resolver.
15231523
last_import_segment: bool,
1524+
blacklisted_binding: Option<&'a NameBinding<'a>>,
15241525

15251526
/// The idents for the primitive types.
15261527
primitive_type_table: PrimitiveTypeTable,
@@ -1871,6 +1872,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
18711872
current_self_type: None,
18721873
current_self_item: None,
18731874
last_import_segment: false,
1875+
blacklisted_binding: None,
18741876

18751877
primitive_type_table: PrimitiveTypeTable::new(),
18761878

@@ -2392,11 +2394,27 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
23922394
ast::UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..],
23932395
_ => &[TypeNS],
23942396
};
2397+
let report_error = |this: &Self, ns| {
2398+
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
2399+
this.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
2400+
};
2401+
23952402
for &ns in nss {
2396-
if let Some(LexicalScopeBinding::Def(..)) =
2397-
self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
2398-
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
2399-
self.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
2403+
match self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
2404+
Some(LexicalScopeBinding::Def(..)) => {
2405+
report_error(self, ns);
2406+
}
2407+
Some(LexicalScopeBinding::Item(binding)) => {
2408+
let orig_blacklisted_binding =
2409+
mem::replace(&mut self.blacklisted_binding, Some(binding));
2410+
if let Some(LexicalScopeBinding::Def(..)) =
2411+
self.resolve_ident_in_lexical_scope(ident, ns, None,
2412+
use_tree.prefix.span) {
2413+
report_error(self, ns);
2414+
}
2415+
self.blacklisted_binding = orig_blacklisted_binding;
2416+
}
2417+
None => {}
24002418
}
24012419
}
24022420
} else if let ast::UseTreeKind::Nested(use_trees) = &use_tree.kind {
@@ -3858,6 +3876,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
38583876
module = Some(ModuleOrUniformRoot::Module(next_module));
38593877
record_segment_def(self, def);
38603878
} else if def == Def::ToolMod && i + 1 != path.len() {
3879+
if binding.is_import() {
3880+
self.session.struct_span_err(
3881+
ident.span, "cannot use a tool module through an import"
3882+
).span_note(
3883+
binding.span, "the tool module imported here"
3884+
).emit();
3885+
}
38613886
let def = Def::NonMacroAttr(NonMacroAttrKind::Tool);
38623887
return PathResult::NonModule(PathResolution::new(def));
38633888
} else if def == Def::Err {

src/librustc_resolve/macros.rs

+40-21
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
499499
.push((path, path_span, kind, parent_scope.clone(), def.ok()));
500500
}
501501

502+
self.prohibit_imported_non_macro_attrs(None, def.ok(), path_span);
502503
def
503504
} else {
504505
let binding = self.early_resolve_ident_in_lexical_scope(
@@ -515,7 +516,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
515516
.push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
516517
}
517518

518-
binding.map(|binding| binding.def_ignoring_ambiguity())
519+
let def = binding.map(|binding| binding.def_ignoring_ambiguity());
520+
self.prohibit_imported_non_macro_attrs(binding.ok(), def.ok(), path_span);
521+
def
519522
}
520523
}
521524

@@ -953,36 +956,34 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
953956
// but its `Def` should coincide with a crate passed with `--extern`
954957
// (otherwise there would be ambiguity) and we can skip feature error in this case.
955958
'ok: {
956-
if !is_import || self.session.features_untracked().uniform_paths {
959+
if !is_import || !rust_2015 {
957960
break 'ok;
958961
}
959962
if ns == TypeNS && use_prelude && self.extern_prelude_get(ident, true).is_some() {
960963
break 'ok;
961964
}
962-
if rust_2015 {
963-
let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span);
964-
let root_module = self.resolve_crate_root(root_ident);
965-
if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
966-
orig_ident, ns, None, false, path_span)
967-
.is_ok() {
968-
break 'ok;
969-
}
965+
let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span);
966+
let root_module = self.resolve_crate_root(root_ident);
967+
if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
968+
orig_ident, ns, None, false, path_span)
969+
.is_ok() {
970+
break 'ok;
970971
}
971972

972-
let msg = "imports can only refer to extern crate names \
973-
passed with `--extern` on stable channel";
974-
let mut err = feature_err(&self.session.parse_sess, "uniform_paths",
975-
ident.span, GateIssue::Language, msg);
976-
973+
let msg = "imports can only refer to extern crate names passed with \
974+
`--extern` in macros originating from 2015 edition";
975+
let mut err = self.session.struct_span_err(ident.span, msg);
977976
let what = self.binding_description(binding, ident,
978977
flags.contains(Flags::MISC_FROM_PRELUDE));
979978
let note_msg = format!("this import refers to {what}", what = what);
980-
if binding.span.is_dummy() {
979+
let label_span = if binding.span.is_dummy() {
981980
err.note(&note_msg);
981+
ident.span
982982
} else {
983983
err.span_note(binding.span, &note_msg);
984-
err.span_label(binding.span, "not an extern crate passed with `--extern`");
985-
}
984+
binding.span
985+
};
986+
err.span_label(label_span, "not an extern crate passed with `--extern`");
986987
err.emit();
987988
}
988989

@@ -1091,6 +1092,20 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
10911092
}
10921093
}
10931094

1095+
fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>,
1096+
def: Option<Def>, span: Span) {
1097+
if let Some(Def::NonMacroAttr(kind)) = def {
1098+
if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
1099+
let msg = format!("cannot use a {} through an import", kind.descr());
1100+
let mut err = self.session.struct_span_err(span, &msg);
1101+
if let Some(binding) = binding {
1102+
err.span_note(binding.span, &format!("the {} imported here", kind.descr()));
1103+
}
1104+
err.emit();
1105+
}
1106+
}
1107+
}
1108+
10941109
fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
10951110
err: &mut DiagnosticBuilder<'a>, span: Span) {
10961111
// First check if this is a locally-defined bang macro.
@@ -1187,17 +1202,21 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
11871202
let ident = ident.modern();
11881203
self.macro_names.insert(ident);
11891204
let def = Def::Macro(def_id, MacroKind::Bang);
1190-
let vis = ty::Visibility::Invisible; // Doesn't matter for legacy bindings
1205+
let is_macro_export = attr::contains_name(&item.attrs, "macro_export");
1206+
let vis = if is_macro_export {
1207+
ty::Visibility::Public
1208+
} else {
1209+
ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
1210+
};
11911211
let binding = (def, vis, item.span, expansion).to_name_binding(self.arenas);
11921212
self.set_binding_parent_module(binding, self.current_module);
11931213
let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding {
11941214
parent_legacy_scope: *current_legacy_scope, binding, ident
11951215
});
11961216
*current_legacy_scope = LegacyScope::Binding(legacy_binding);
11971217
self.all_macros.insert(ident.name, def);
1198-
if attr::contains_name(&item.attrs, "macro_export") {
1218+
if is_macro_export {
11991219
let module = self.graph_root;
1200-
let vis = ty::Visibility::Public;
12011220
self.define(module, ident, MacroNS,
12021221
(def, vis, item.span, expansion, IsMacroExport));
12031222
} else {

src/librustc_resolve/resolve_imports.rs

+41-17
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ use std::{mem, ptr};
4242
#[derive(Clone, Debug)]
4343
pub enum ImportDirectiveSubclass<'a> {
4444
SingleImport {
45-
target: Ident,
4645
source: Ident,
47-
result: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
46+
target: Ident,
47+
source_bindings: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
48+
target_bindings: PerNS<Cell<Option<&'a NameBinding<'a>>>>,
4849
type_ns_only: bool,
4950
},
5051
GlobImport {
@@ -227,14 +228,30 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
227228
}
228229

229230
let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
231+
if let Some(blacklisted_binding) = this.blacklisted_binding {
232+
if ptr::eq(binding, blacklisted_binding) {
233+
return Err((Determined, Weak::No));
234+
}
235+
}
230236
// `extern crate` are always usable for backwards compatibility, see issue #37020,
231237
// remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
232238
let usable = this.is_accessible(binding.vis) || binding.is_extern_crate();
233239
if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
234240
};
235241

236242
if record_used {
237-
return resolution.binding.ok_or((Determined, Weak::No)).and_then(|binding| {
243+
return resolution.binding.and_then(|binding| {
244+
// If the primary binding is blacklisted, search further and return the shadowed
245+
// glob binding if it exists. What we really want here is having two separate
246+
// scopes in a module - one for non-globs and one for globs, but until that's done
247+
// use this hack to avoid inconsistent resolution ICEs during import validation.
248+
if let Some(blacklisted_binding) = self.blacklisted_binding {
249+
if ptr::eq(binding, blacklisted_binding) {
250+
return resolution.shadowed_glob;
251+
}
252+
}
253+
Some(binding)
254+
}).ok_or((Determined, Weak::No)).and_then(|binding| {
238255
if self.last_import_segment && check_usable(self, binding).is_err() {
239256
Err((Determined, Weak::No))
240257
} else {
@@ -646,10 +663,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
646663
if let Some((span, err, note)) = self.finalize_import(import) {
647664
errors = true;
648665

649-
if let SingleImport { source, ref result, .. } = import.subclass {
666+
if let SingleImport { source, ref source_bindings, .. } = import.subclass {
650667
if source.name == "self" {
651668
// Silence `unresolved import` error if E0429 is already emitted
652-
if let Err(Determined) = result.value_ns.get() {
669+
if let Err(Determined) = source_bindings.value_ns.get() {
653670
continue;
654671
}
655672
}
@@ -769,9 +786,11 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
769786
};
770787

771788
directive.imported_module.set(Some(module));
772-
let (source, target, result, type_ns_only) = match directive.subclass {
773-
SingleImport { source, target, ref result, type_ns_only } =>
774-
(source, target, result, type_ns_only),
789+
let (source, target, source_bindings, target_bindings, type_ns_only) =
790+
match directive.subclass {
791+
SingleImport { source, target, ref source_bindings,
792+
ref target_bindings, type_ns_only } =>
793+
(source, target, source_bindings, target_bindings, type_ns_only),
775794
GlobImport { .. } => {
776795
self.resolve_glob_import(directive);
777796
return true;
@@ -781,7 +800,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
781800

782801
let mut indeterminate = false;
783802
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
784-
if let Err(Undetermined) = result[ns].get() {
803+
if let Err(Undetermined) = source_bindings[ns].get() {
785804
// For better failure detection, pretend that the import will
786805
// not define any names while resolving its module path.
787806
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
@@ -790,13 +809,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
790809
);
791810
directive.vis.set(orig_vis);
792811

793-
result[ns].set(binding);
812+
source_bindings[ns].set(binding);
794813
} else {
795814
return
796815
};
797816

798817
let parent = directive.parent_scope.module;
799-
match result[ns].get() {
818+
match source_bindings[ns].get() {
800819
Err(Undetermined) => indeterminate = true,
801820
Err(Determined) => {
802821
this.update_resolution(parent, target, ns, |_, resolution| {
@@ -814,6 +833,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
814833
}
815834
Ok(binding) => {
816835
let imported_binding = this.import(binding, directive);
836+
target_bindings[ns].set(Some(imported_binding));
817837
let conflict = this.try_define(parent, target, ns, imported_binding);
818838
if let Err(old_binding) = conflict {
819839
this.report_conflict(parent, target, ns, imported_binding, old_binding);
@@ -885,8 +905,9 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
885905
PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(),
886906
};
887907

888-
let (ident, result, type_ns_only) = match directive.subclass {
889-
SingleImport { source, ref result, type_ns_only, .. } => (source, result, type_ns_only),
908+
let (ident, source_bindings, target_bindings, type_ns_only) = match directive.subclass {
909+
SingleImport { source, ref source_bindings, ref target_bindings, type_ns_only, .. } =>
910+
(source, source_bindings, target_bindings, type_ns_only),
890911
GlobImport { is_prelude, ref max_vis } => {
891912
if directive.module_path.len() <= 1 {
892913
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
@@ -925,17 +946,20 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
925946
let mut all_ns_err = true;
926947
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
927948
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
949+
let orig_blacklisted_binding =
950+
mem::replace(&mut this.blacklisted_binding, target_bindings[ns].get());
928951
let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true);
929952
let binding = this.resolve_ident_in_module(
930953
module, ident, ns, Some(&directive.parent_scope), true, directive.span
931954
);
932955
this.last_import_segment = orig_last_import_segment;
956+
this.blacklisted_binding = orig_blacklisted_binding;
933957
directive.vis.set(orig_vis);
934958

935959
match binding {
936960
Ok(binding) => {
937961
// Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
938-
let initial_def = result[ns].get().map(|initial_binding| {
962+
let initial_def = source_bindings[ns].get().map(|initial_binding| {
939963
all_ns_err = false;
940964
this.record_use(ident, ns, initial_binding,
941965
directive.module_path.is_empty());
@@ -1040,7 +1064,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
10401064
let mut reexport_error = None;
10411065
let mut any_successful_reexport = false;
10421066
self.per_ns(|this, ns| {
1043-
if let Ok(binding) = result[ns].get() {
1067+
if let Ok(binding) = source_bindings[ns].get() {
10441068
let vis = directive.vis.get();
10451069
if !binding.pseudo_vis().is_at_least(vis, &*this) {
10461070
reexport_error = Some((ns, binding));
@@ -1084,7 +1108,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
10841108
let mut full_path = directive.module_path.clone();
10851109
full_path.push(Segment::from_ident(ident));
10861110
self.per_ns(|this, ns| {
1087-
if let Ok(binding) = result[ns].get() {
1111+
if let Ok(binding) = source_bindings[ns].get() {
10881112
this.lint_if_path_starts_with_module(
10891113
directive.crate_lint(),
10901114
&full_path,
@@ -1098,7 +1122,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
10981122
// Record what this import resolves to for later uses in documentation,
10991123
// this may resolve to either a value or a type, but for documentation
11001124
// purposes it's good enough to just favor one over the other.
1101-
self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
1125+
self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
11021126
let mut def = binding.def();
11031127
if let Def::Macro(def_id, _) = def {
11041128
// `DefId`s from the "built-in macro crate" should not leak from resolve because

0 commit comments

Comments
 (0)