Skip to content

Commit 097b6d6

Browse files
committed
item_like_imports: Allow glob imports with a given visibility
to reexport some (but not all) names with less visibility.
1 parent c56a5af commit 097b6d6

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ use rustc::hir::def::*;
2626
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
2727
use rustc::ty::{self, VariantKind};
2828

29+
use std::cell::Cell;
30+
2931
use syntax::ast::Name;
3032
use syntax::attr;
3133
use syntax::parse::token;
@@ -176,7 +178,10 @@ impl<'b> Resolver<'b> {
176178
}
177179
}
178180
ViewPathGlob(_) => {
179-
let subclass = GlobImport { is_prelude: is_prelude };
181+
let subclass = GlobImport {
182+
is_prelude: is_prelude,
183+
max_vis: Cell::new(ty::Visibility::PrivateExternal),
184+
};
180185
let span = view_path.span;
181186
self.add_import_directive(module_path, subclass, span, item.id, vis);
182187
}

src/librustc_resolve/resolve_imports.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ pub enum ImportDirectiveSubclass<'a> {
5252
value_result: Cell<Result<&'a NameBinding<'a>, Determinacy>>,
5353
type_result: Cell<Result<&'a NameBinding<'a>, Determinacy>>,
5454
},
55-
GlobImport { is_prelude: bool },
55+
GlobImport {
56+
is_prelude: bool,
57+
max_vis: Cell<ty::Visibility>, // The visibility of the greatest reexport.
58+
},
5659
}
5760

5861
impl<'a> ImportDirectiveSubclass<'a> {
@@ -276,7 +279,7 @@ impl<'a> Resolver<'a> {
276279
}
277280
// We don't add prelude imports to the globs since they only affect lexical scopes,
278281
// which are not relevant to import resolution.
279-
GlobImport { is_prelude: true } => {}
282+
GlobImport { is_prelude: true, .. } => {}
280283
GlobImport { .. } => self.current_module.globs.borrow_mut().push(directive),
281284
}
282285
}
@@ -292,6 +295,12 @@ impl<'a> Resolver<'a> {
292295
binding.pseudo_vis()
293296
};
294297

298+
if let GlobImport { ref max_vis, .. } = directive.subclass {
299+
if vis == directive.vis.get() || vis.is_at_least(max_vis.get(), self) {
300+
max_vis.set(vis)
301+
}
302+
}
303+
295304
NameBinding {
296305
kind: NameBindingKind::Import {
297306
binding: binding,
@@ -562,7 +571,15 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
562571
let msg = "Cannot glob-import a module into itself.".into();
563572
return Failed(Some((directive.span, msg)));
564573
}
565-
GlobImport { .. } => return Success(()),
574+
GlobImport { is_prelude, ref max_vis } => {
575+
if !is_prelude &&
576+
max_vis.get() != ty::Visibility::PrivateExternal && // Allow empty globs.
577+
!max_vis.get().is_at_least(directive.vis.get(), self) {
578+
let msg = "A non-empty glob must import something with the glob's visibility";
579+
self.session.span_err(directive.span, msg);
580+
}
581+
return Success(());
582+
}
566583
};
567584

568585
for &(ns, result) in &[(ValueNS, value_result), (TypeNS, type_result)] {
@@ -677,7 +694,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
677694
return;
678695
} else if module.def_id() == directive.parent.def_id() {
679696
return;
680-
} else if let GlobImport { is_prelude: true } = directive.subclass {
697+
} else if let GlobImport { is_prelude: true, .. } = directive.subclass {
681698
self.prelude = Some(module);
682699
return;
683700
}

0 commit comments

Comments
 (0)