Skip to content

Commit 8c6421f

Browse files
authored
Rollup merge of rust-lang#35063 - jseyfried:avoid_importing_inaccessible_names, r=nrc
resolve: Exclude inaccessible names from single imports If a single import resolves to an inaccessible name in some but not all namespaces, avoid importing the name in the inaccessible namespaces. Currently, the inaccessible namespaces are imported but cause a privacy error when used. r? @nrc
2 parents 6234610 + 8205691 commit 8c6421f

File tree

3 files changed

+43
-58
lines changed

3 files changed

+43
-58
lines changed

src/librustc_resolve/lib.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -825,8 +825,6 @@ enum NameBindingKind<'a> {
825825
Import {
826826
binding: &'a NameBinding<'a>,
827827
directive: &'a ImportDirective<'a>,
828-
// Some(error) if using this imported name causes the import to be a privacy error
829-
privacy_error: Option<Box<PrivacyError<'a>>>,
830828
},
831829
}
832830

@@ -1206,16 +1204,11 @@ impl<'a> Resolver<'a> {
12061204
self.used_crates.insert(krate);
12071205
}
12081206

1209-
let (directive, privacy_error) = match binding.kind {
1210-
NameBindingKind::Import { directive, ref privacy_error, .. } =>
1211-
(directive, privacy_error),
1207+
let directive = match binding.kind {
1208+
NameBindingKind::Import { directive, .. } => directive,
12121209
_ => return,
12131210
};
12141211

1215-
if let Some(error) = privacy_error.as_ref() {
1216-
self.privacy_errors.push((**error).clone());
1217-
}
1218-
12191212
if !self.make_glob_map {
12201213
return;
12211214
}

src/librustc_resolve/resolve_imports.rs

+33-41
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,11 @@ pub struct ImportDirective<'a> {
7373
impl<'a> ImportDirective<'a> {
7474
// Given the binding to which this directive resolves in a particular namespace,
7575
// this returns the binding for the name this directive defines in that namespace.
76-
fn import(&'a self, binding: &'a NameBinding<'a>, privacy_error: Option<Box<PrivacyError<'a>>>)
77-
-> NameBinding<'a> {
76+
fn import(&'a self, binding: &'a NameBinding<'a>) -> NameBinding<'a> {
7877
NameBinding {
7978
kind: NameBindingKind::Import {
8079
binding: binding,
8180
directive: self,
82-
privacy_error: privacy_error,
8381
},
8482
span: self.span,
8583
vis: self.vis,
@@ -328,7 +326,7 @@ impl<'a> ::ModuleS<'a> {
328326
fn define_in_glob_importers(&self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>) {
329327
if !binding.is_importable() || !binding.is_pseudo_public() { return }
330328
for &(importer, directive) in self.glob_importers.borrow_mut().iter() {
331-
let _ = importer.try_define_child(name, ns, directive.import(binding, None));
329+
let _ = importer.try_define_child(name, ns, directive.import(binding));
332330
}
333331
}
334332
}
@@ -409,7 +407,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
409407
span: DUMMY_SP,
410408
vis: ty::Visibility::Public,
411409
});
412-
let dummy_binding = directive.import(dummy_binding, None);
410+
let dummy_binding = directive.import(dummy_binding);
413411

414412
let _ = source_module.try_define_child(target, ValueNS, dummy_binding.clone());
415413
let _ = source_module.try_define_child(target, TypeNS, dummy_binding);
@@ -494,38 +492,37 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
494492
self.resolver.resolve_name_in_module(target_module, source, TypeNS, false, true);
495493

496494
let module_ = self.resolver.current_module;
495+
let mut privacy_error = true;
497496
for &(ns, result, determined) in &[(ValueNS, &value_result, value_determined),
498497
(TypeNS, &type_result, type_determined)] {
499-
if determined.get() { continue }
500-
if let Indeterminate = *result { continue }
501-
502-
determined.set(true);
503-
if let Success(binding) = *result {
504-
if !binding.is_importable() {
498+
match *result {
499+
Failed(..) if !determined.get() => {
500+
determined.set(true);
501+
module_.update_resolution(target, ns, |resolution| {
502+
resolution.single_imports.directive_failed()
503+
});
504+
}
505+
Success(binding) if !binding.is_importable() => {
505506
let msg = format!("`{}` is not directly importable", target);
506507
span_err!(self.resolver.session, directive.span, E0253, "{}", &msg);
507508
// Do not import this illegal binding. Import a dummy binding and pretend
508509
// everything is fine
509510
self.import_dummy_binding(module_, directive);
510511
return Success(());
511512
}
512-
513-
let privacy_error = if !self.resolver.is_accessible(binding.vis) {
514-
Some(Box::new(PrivacyError(directive.span, source, binding)))
515-
} else {
516-
None
517-
};
518-
519-
let imported_binding = directive.import(binding, privacy_error);
520-
let conflict = module_.try_define_child(target, ns, imported_binding);
521-
if let Err(old_binding) = conflict {
522-
let binding = &directive.import(binding, None);
523-
self.resolver.report_conflict(module_, target, ns, binding, old_binding);
513+
Success(binding) if !self.resolver.is_accessible(binding.vis) => {}
514+
Success(binding) if !determined.get() => {
515+
determined.set(true);
516+
let imported_binding = directive.import(binding);
517+
let conflict = module_.try_define_child(target, ns, imported_binding);
518+
if let Err(old_binding) = conflict {
519+
let binding = &directive.import(binding);
520+
self.resolver.report_conflict(module_, target, ns, binding, old_binding);
521+
}
522+
privacy_error = false;
524523
}
525-
} else {
526-
module_.update_resolution(target, ns, |resolution| {
527-
resolution.single_imports.directive_failed();
528-
});
524+
Success(_) => privacy_error = false,
525+
_ => {}
529526
}
530527
}
531528

@@ -556,6 +553,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
556553
_ => (),
557554
}
558555

556+
if privacy_error {
557+
for &(ns, result) in &[(ValueNS, &value_result), (TypeNS, &type_result)] {
558+
let binding = match *result { Success(binding) => binding, _ => continue };
559+
self.resolver.privacy_errors.push(PrivacyError(directive.span, source, binding));
560+
let _ = module_.try_define_child(target, ns, directive.import(binding));
561+
}
562+
}
563+
559564
match (&value_result, &type_result) {
560565
(&Success(binding), _) if !binding.pseudo_vis()
561566
.is_at_least(directive.vis, self.resolver) &&
@@ -592,19 +597,6 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
592597
_ => {}
593598
}
594599

595-
// Report a privacy error here if all successful namespaces are privacy errors.
596-
let mut privacy_error = None;
597-
for &ns in &[ValueNS, TypeNS] {
598-
privacy_error = match module_.resolve_name(target, ns, true) {
599-
Success(&NameBinding {
600-
kind: NameBindingKind::Import { ref privacy_error, .. }, ..
601-
}) => privacy_error.as_ref().map(|error| (**error).clone()),
602-
_ => continue,
603-
};
604-
if privacy_error.is_none() { break }
605-
}
606-
privacy_error.map(|error| self.resolver.privacy_errors.push(error));
607-
608600
// Record what this import resolves to for later uses in documentation,
609601
// this may resolve to either a value or a type, but for documentation
610602
// purposes it's good enough to just favor one over the other.
@@ -652,7 +644,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
652644
}).collect::<Vec<_>>();
653645
for ((name, ns), binding) in bindings {
654646
if binding.is_importable() && binding.is_pseudo_public() {
655-
let _ = module_.try_define_child(name, ns, directive.import(binding, None));
647+
let _ = module_.try_define_child(name, ns, directive.import(binding));
656648
}
657649
}
658650

src/test/compile-fail/privacy-ns2.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ pub mod foo1 {
2525
}
2626

2727
fn test_single1() {
28-
use foo1::Bar; //~ ERROR function `Bar` is private
28+
use foo1::Bar;
2929

30-
Bar();
30+
Bar(); //~ ERROR unresolved name `Bar`
3131
}
3232

3333
fn test_list1() {
34-
use foo1::{Bar,Baz}; //~ ERROR `Bar` is private
34+
use foo1::{Bar,Baz};
3535

36-
Bar();
36+
Bar(); //~ ERROR unresolved name `Bar`
3737
}
3838

3939
// private type, public value
@@ -46,15 +46,15 @@ pub mod foo2 {
4646
}
4747

4848
fn test_single2() {
49-
use foo2::Bar; //~ ERROR trait `Bar` is private
49+
use foo2::Bar;
5050

51-
let _x : Box<Bar>;
51+
let _x : Box<Bar>; //~ ERROR type name `Bar` is undefined
5252
}
5353

5454
fn test_list2() {
55-
use foo2::{Bar,Baz}; //~ ERROR `Bar` is private
55+
use foo2::{Bar,Baz};
5656

57-
let _x: Box<Bar>;
57+
let _x: Box<Bar>; //~ ERROR type name `Bar` is undefined
5858
}
5959

6060
// neither public

0 commit comments

Comments
 (0)