diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-08-19 22:52:26 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-09-01 22:30:24 +0000 |
| commit | c56a5afd4d1c4717770efa693e69eead13abee34 (patch) | |
| tree | b0168faebf1cfe667474aac31cb59ac89552dd79 /src/librustc_resolve | |
| parent | aad1f3cbf3340afd0685b79981a59f0ba3e83116 (diff) | |
| download | rust-c56a5afd4d1c4717770efa693e69eead13abee34.tar.gz rust-c56a5afd4d1c4717770efa693e69eead13abee34.zip | |
item_like_imports: Allow single imports with a given visibility
to reexport some (but not all) namespaces with less visibility.
Diffstat (limited to 'src/librustc_resolve')
| -rw-r--r-- | src/librustc_resolve/resolve_imports.rs | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index c7cb3a35178..7084aa685ae 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -285,13 +285,20 @@ impl<'a> Resolver<'a> { // return the corresponding binding defined by the import directive. fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>) -> NameBinding<'a> { + let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) || + !directive.is_glob() && binding.is_extern_crate() { // c.f. `PRIVATE_IN_PUBLIC` + directive.vis.get() + } else { + binding.pseudo_vis() + }; + NameBinding { kind: NameBindingKind::Import { binding: binding, directive: directive, }, span: directive.span, - vis: directive.vis.get(), + vis: vis, } } @@ -597,22 +604,44 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } } + let session = self.session; + let reexport_error = || { + let msg = format!("`{}` is private, and cannot be reexported", name); + let note_msg = + format!("consider marking `{}` as `pub` in the imported module", name); + struct_span_err!(session, directive.span, E0364, "{}", &msg) + .span_note(directive.span, ¬e_msg) + .emit(); + }; + + let extern_crate_lint = || { + let msg = format!("extern crate `{}` is private, and cannot be reexported \ + (error E0364), consider declaring with `pub`", + name); + session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg); + }; + match (value_result, type_result) { + // With `#![feature(item_like_imports)]`, all namespaces + // must be re-exported with extra visibility for an error to occur. + (Ok(value_binding), Ok(type_binding)) if self.new_import_semantics => { + let vis = directive.vis.get(); + if !value_binding.pseudo_vis().is_at_least(vis, self) && + !type_binding.pseudo_vis().is_at_least(vis, self) { + reexport_error(); + } else if type_binding.is_extern_crate() && + !type_binding.vis.is_at_least(vis, self) { + extern_crate_lint(); + } + } + (Ok(binding), _) if !binding.pseudo_vis().is_at_least(directive.vis.get(), self) => { - let msg = format!("`{}` is private, and cannot be reexported", name); - let note_msg = - format!("consider marking `{}` as `pub` in the imported module", name); - struct_span_err!(self.session, directive.span, E0364, "{}", &msg) - .span_note(directive.span, ¬e_msg) - .emit(); + reexport_error(); } (_, Ok(binding)) if !binding.pseudo_vis().is_at_least(directive.vis.get(), self) => { if binding.is_extern_crate() { - let msg = format!("extern crate `{}` is private, and cannot be reexported \ - (error E0364), consider declaring with `pub`", - name); - self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg); + extern_crate_lint(); } else { struct_span_err!(self.session, directive.span, E0365, "`{}` is private, and cannot be reexported", name) |
