diff options
| author | bors <bors@rust-lang.org> | 2017-11-04 18:07:07 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-11-04 18:07:07 +0000 |
| commit | d762b1d6c67db12e117186d94d70e46cddb22965 (patch) | |
| tree | cbb52929585ad9ea4e52a9dde6e9170375ccf04a /src/librustc_resolve | |
| parent | 98e4b6845f111d297fa2bff759b6f15855280161 (diff) | |
| parent | 86c62d02eebb037faf7c0752a9c472181e5608cb (diff) | |
| download | rust-d762b1d6c67db12e117186d94d70e46cddb22965.tar.gz rust-d762b1d6c67db12e117186d94d70e46cddb22965.zip | |
Auto merge of #45394 - davidtwco:rfc-2008, r=petrochenkov
RFC 2008: Future-proofing enums/structs with #[non_exhaustive] attribute This work-in-progress pull request contains my changes to implement [RFC 2008](https://github.com/rust-lang/rfcs/pull/2008). The related tracking issue is #44109. As of writing, enum-related functionality is not included and there are some issues related to tuple/unit structs. Enum related tests are currently ignored. WIP PR requested by @nikomatsakis [in Gitter](https://gitter.im/rust-impl-period/WG-compiler-middle?at=59e90e6297cedeb0482ade3e).
Diffstat (limited to 'src/librustc_resolve')
| -rw-r--r-- | src/librustc_resolve/build_reduced_graph.rs | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index ef556019699..a10bce29342 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -338,11 +338,22 @@ impl<'a> Resolver<'a> { // These items live in both the type and value namespaces. ItemKind::Struct(ref struct_def, _) => { // Define a name in the type namespace. - let def = Def::Struct(self.definitions.local_def_id(item.id)); + let def_id = self.definitions.local_def_id(item.id); + let def = Def::Struct(def_id); self.define(parent, ident, TypeNS, (def, vis, sp, expansion)); - // Record field names for error reporting. let mut ctor_vis = vis; + + let has_non_exhaustive = item.attrs.iter() + .any(|item| item.check_name("non_exhaustive")); + + // If the structure is marked as non_exhaustive then lower the visibility + // to within the crate. + if has_non_exhaustive && vis == ty::Visibility::Public { + ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)); + } + + // Record field names for error reporting. let field_names = struct_def.fields().iter().filter_map(|field| { let field_vis = self.resolve_visibility(&field.vis); if ctor_vis.is_at_least(field_vis, &*self) { @@ -414,6 +425,7 @@ impl<'a> Resolver<'a> { // value namespace, they are reserved for possible future use. let ctor_kind = CtorKind::from_ast(&variant.node.data); let ctor_def = Def::VariantCtor(def_id, ctor_kind); + self.define(parent, ident, ValueNS, (ctor_def, vis, variant.span, expansion)); } |
