Auto merge of #45401 - zackmdavis:crate_shorthand_visibility_modifier, r=nikomatsakis

`crate` shorthand visibility modifier

cc #45388.

r? @nikomatsakis
This commit is contained in:
bors 2017-10-24 12:24:16 +00:00
commit fbc3642ef1
14 changed files with 97 additions and 10 deletions

View file

@ -0,0 +1,20 @@
# `crate_visibility_modifier`
The tracking issue for this feature is: [#45388]
[#45388]: https://github.com/rust-lang/rust/issues/45388
-----
The `crate_visibility_modifier` feature allows the `crate` keyword to be used
as a visibility modifier synonymous to `pub(crate)`, indicating that a type
(function, _&c._) is to be visible to the entire enclosing crate, but not to
other crates.
```rust
#![feature(crate_visibility_modifier)]
crate struct Foo {
bar: usize,
}
```

View file

@ -2667,7 +2667,7 @@ impl<'a> LoweringContext<'a> {
-> hir::Visibility {
match *v {
Visibility::Public => hir::Public,
Visibility::Crate(_) => hir::Visibility::Crate,
Visibility::Crate(..) => hir::Visibility::Crate,
Visibility::Restricted { ref path, id } => {
hir::Visibility::Restricted {
path: P(self.lower_path(id, path, ParamMode::Explicit, true)),

View file

@ -1788,10 +1788,19 @@ impl PolyTraitRef {
}
}
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum CrateSugar {
/// Source is `pub(crate)`
PubCrate,
/// Source is (just) `crate`
JustCrate,
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Visibility {
Public,
Crate(Span),
Crate(Span, CrateSugar),
Restricted { path: P<Path>, id: NodeId },
Inherited,
}

View file

@ -401,6 +401,9 @@ declare_features! (
// Trait object syntax with `dyn` prefix
(active, dyn_trait, "1.22.0", Some(44662)),
// `crate` as visibility modifier, synonymous to `pub(crate)`
(active, crate_visibility_modifier, "1.23.0", Some(45388)),
);
declare_features! (
@ -1582,6 +1585,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
visit::walk_impl_item(self, ii);
}
fn visit_vis(&mut self, vis: &'a ast::Visibility) {
if let ast::Visibility::Crate(span, ast::CrateSugar::JustCrate) = *vis {
gate_feature_post!(&self, crate_visibility_modifier, span,
"`crate` visibility modifier is experimental");
}
visit::walk_vis(self, vis);
}
fn visit_generics(&mut self, g: &'a ast::Generics) {
for t in &g.ty_params {
if !t.attrs.is_empty() {

View file

@ -36,7 +36,7 @@ use ast::SelfKind;
use ast::{TraitItem, TraitRef, TraitObjectSyntax};
use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds};
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
use ast::{Visibility, WhereClause};
use ast::{Visibility, WhereClause, CrateSugar};
use ast::{BinOpKind, UnOp};
use ast::{RangeEnd, RangeSyntax};
use {ast, attr};
@ -5327,6 +5327,10 @@ impl<'a> Parser<'a> {
pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibility> {
maybe_whole!(self, NtVis, |x| x);
if self.eat_keyword(keywords::Crate) {
return Ok(Visibility::Crate(self.prev_span, CrateSugar::JustCrate));
}
if !self.eat_keyword(keywords::Pub) {
return Ok(Visibility::Inherited)
}
@ -5340,7 +5344,7 @@ impl<'a> Parser<'a> {
// `pub(crate)`
self.bump(); // `(`
self.bump(); // `crate`
let vis = Visibility::Crate(self.prev_span);
let vis = Visibility::Crate(self.prev_span, CrateSugar::PubCrate);
self.expect(&token::CloseDelim(token::Paren))?; // `)`
return Ok(vis)
} else if self.look_ahead(1, |t| t.is_keyword(keywords::In)) {

View file

@ -1440,7 +1440,10 @@ impl<'a> State<'a> {
pub fn print_visibility(&mut self, vis: &ast::Visibility) -> io::Result<()> {
match *vis {
ast::Visibility::Public => self.word_nbsp("pub"),
ast::Visibility::Crate(_) => self.word_nbsp("pub(crate)"),
ast::Visibility::Crate(_, sugar) => match sugar {
ast::CrateSugar::PubCrate => self.word_nbsp("pub(crate)"),
ast::CrateSugar::JustCrate => self.word_nbsp("crate")
}
ast::Visibility::Restricted { ref path, .. } => {
let path = to_string(|s| s.print_path(path, false, 0, true));
if path == "self" || path == "super" {

View file

@ -0,0 +1,18 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
crate struct Bender { //~ ERROR `crate` visibility modifier is experimental
earth: bool,
fire: bool,
air: bool,
water: bool,
}
fn main() {}

View file

@ -8,14 +8,19 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(crate_visibility_modifier)]
pub(crate) struct Crate;
#[derive(Default)]
pub struct Universe {
pub x: i32,
pub(crate) y: i32
pub(crate) y: i32,
crate z: i32,
}
impl Universe {
pub fn f(&self) {}
pub(crate) fn g(&self) {}
crate fn h(&self) {}
}

View file

@ -8,12 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(crate_visibility_modifier)]
mod foo {
struct Priv;
mod bar {
use foo::Priv;
pub(super) fn f(_: Priv) {}
pub(crate) fn g(_: Priv) {} //~ ERROR E0446
crate fn h(_: Priv) {} //~ ERROR E0446
}
}

View file

@ -50,8 +50,10 @@ fn main() {
let u = Universe::default();
let _ = u.x;
let _ = u.y; //~ ERROR private
let _ = u.z; //~ ERROR private
u.f();
u.g(); //~ ERROR private
u.h(); //~ ERROR private
}
mod pathological {

View file

@ -16,6 +16,6 @@ impl Foo {
fn foo() {}
#[stable(feature = "rust1", since = "1.0.0")]
} //~ ERROR expected one of `const`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`
} //~ ERROR expected one of `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`
fn main() {}

View file

@ -14,6 +14,6 @@ struct Foo;
impl Foo {
#[stable(feature = "rust1", since = "1.0.0")]
} //~ ERROR expected one of `const`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`
} //~ ERROR expected one of `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`
fn main() {}

View file

@ -15,4 +15,4 @@ struct S;
impl S {
static fn f() {}
}
//~^^ ERROR expected one of `const`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`
//~^^ ERROR expected one of `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`

View file

@ -9,7 +9,7 @@
// except according to those terms.
#![allow(dead_code, unused_imports)]
#![feature(macro_vis_matcher)]
#![feature(macro_vis_matcher, crate_visibility_modifier)]
/**
Ensure that `:vis` matches can be captured in existing positions, and passed
@ -64,6 +64,18 @@ mod with_pub_restricted {
vis_passthru! { pub(crate) use A as I; }
}
mod with_crate {
vis_passthru! { crate const A: i32 = 0; }
vis_passthru! { crate enum B {} }
vis_passthru! { crate extern "C" fn c() {} }
vis_passthru! { crate mod d {} }
vis_passthru! { crate static E: i32 = 0; }
vis_passthru! { crate struct F; }
vis_passthru! { crate trait G {} }
vis_passthru! { crate type H = i32; }
vis_passthru! { crate use A as I; }
}
mod garden {
mod with_pub_restricted_path {
vis_passthru! { pub(in garden) const A: i32 = 0; }