resolve: Resolve visibilities on fields with non-builtin attributes

This commit is contained in:
Vadim Petrochenkov 2019-12-07 00:03:58 +03:00
parent 7de9402b77
commit 9e6725dcfe
3 changed files with 62 additions and 4 deletions

View file

@ -192,6 +192,14 @@ impl<'a> AsMut<Resolver<'a>> for BuildReducedGraphVisitor<'a, '_> {
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
self.resolve_visibility_speculative(vis, false)
}
fn resolve_visibility_speculative(
&mut self,
vis: &ast::Visibility,
speculative: bool,
) -> ty::Visibility {
let parent_scope = &self.parent_scope;
match vis.node {
ast::VisibilityKind::Public => ty::Visibility::Public,
@ -239,13 +247,15 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
&segments,
Some(TypeNS),
parent_scope,
true,
!speculative,
path.span,
CrateLint::SimplePath(id),
) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
let res = module.res().expect("visibility resolved to unnamed block");
self.r.record_partial_res(id, PartialRes::new(res));
if !speculative {
self.r.record_partial_res(id, PartialRes::new(res));
}
if module.is_normal() {
if res == Res::Err {
ty::Visibility::Public
@ -747,7 +757,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
// NOTE: The field may be an expansion placeholder, but expansion sets correct
// visibilities for unnamed field placeholders specifically, so the constructor
// visibility should still be determined correctly.
let field_vis = self.resolve_visibility(&field.vis);
let field_vis = self.resolve_visibility_speculative(&field.vis, true);
if ctor_vis.is_at_least(field_vis, &*self.r) {
ctor_vis = field_vis;
}
@ -774,7 +784,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
// Record field names for error reporting.
let field_names = vdata.fields().iter().map(|field| {
self.resolve_visibility(&field.vis);
respan(field.span, field.ident.map_or(kw::Invalid, |ident| ident.name))
}).collect();
let item_def_id = self.r.definitions.local_def_id(item.id);
@ -1281,6 +1290,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
if sf.is_placeholder {
self.visit_invoc(sf.id);
} else {
self.resolve_visibility(&sf.vis);
visit::walk_struct_field(self, sf);
}
}

View file

@ -0,0 +1,26 @@
// Non-builtin attributes do not mess with field visibility resolution (issue #67006).
mod internal {
struct S {
#[rustfmt::skip]
pub(in crate::internal) field: u8 // OK
}
struct Z(
#[rustfmt::skip]
pub(in crate::internal) u8 // OK
);
}
struct S {
#[rustfmt::skip]
pub(in nonexistent) field: u8 //~ ERROR failed to resolve
}
struct Z(
#[rustfmt::skip]
pub(in nonexistent) u8 //~ ERROR failed to resolve
//~| ERROR cannot determine resolution for the visibility
);
fn main() {}

View file

@ -0,0 +1,22 @@
error[E0578]: cannot determine resolution for the visibility
--> $DIR/field-attributes-vis-unresolved.rs:22:12
|
LL | pub(in nonexistent) u8
| ^^^^^^^^^^^
error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
--> $DIR/field-attributes-vis-unresolved.rs:17:12
|
LL | pub(in nonexistent) field: u8
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
--> $DIR/field-attributes-vis-unresolved.rs:22:12
|
LL | pub(in nonexistent) u8
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0433, E0578.
For more information about an error, try `rustc --explain E0433`.