提交 214b0f22 编写于 作者: Z Zack M. Davis

`crate` shorthand visibility modifier

With regrets, this breaks rustfmt and rls.

This is in the matter of #45388.
上级 4c053db2
# `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,
}
```
......@@ -2666,7 +2666,7 @@ fn lower_visibility(&mut self,
-> 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)),
......
......@@ -1787,10 +1787,19 @@ pub fn new(lifetimes: Vec<LifetimeDef>, path: Path, span: Span) -> Self {
}
}
#[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,
}
......
......@@ -401,6 +401,9 @@ pub fn new() -> 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 @@ fn visit_impl_item(&mut self, ii: &'a ast::ImplItem) {
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() {
......
......@@ -36,7 +36,7 @@
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};
......@@ -5325,6 +5325,10 @@ fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
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)
}
......@@ -5338,7 +5342,7 @@ pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibili
// `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)) {
......
......@@ -1440,7 +1440,10 @@ pub fn print_variants(&mut self,
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" {
......
// 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() {}
......@@ -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) {}
}
......@@ -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
}
}
......
......@@ -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 {
......
......@@ -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() {}
......@@ -14,6 +14,6 @@
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() {}
......@@ -15,4 +15,4 @@
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`
......@@ -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; }
......
......@@ -29,7 +29,7 @@ miri = "Broken"
clippy = "Compiling"
# ping @nrc
rls = "Testing"
rls = "Broken"
# ping @nrc
rustfmt = "Testing"
rustfmt = "Broken"
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册