Skip to content

Rollup of 5 pull requests #57955

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/libcore/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ mod flatten;
mod zip;

pub use self::chain::Chain;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::flatten::{FlatMap, Flatten};
pub use self::zip::Zip;
pub(crate) use self::zip::TrustedRandomAccess;
2 changes: 2 additions & 0 deletions src/libcore/iter/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -5,9 +5,11 @@ mod collect;
mod accum;
mod marker;

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::iterator::Iterator;
pub use self::double_ended::DoubleEndedIterator;
pub use self::exact_size::ExactSizeIterator;
pub use self::collect::{FromIterator, IntoIterator, Extend};
pub use self::accum::{Sum, Product};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::marker::{FusedIterator, TrustedLen};
10 changes: 10 additions & 0 deletions src/librustc/hir/def.rs
Original file line number Diff line number Diff line change
@@ -252,12 +252,14 @@ impl NonMacroAttrKind {
}

impl Def {
/// Return the `DefId` of this `Def` if it has an id, else panic.
pub fn def_id(&self) -> DefId {
self.opt_def_id().unwrap_or_else(|| {
bug!("attempted .def_id() on invalid def: {:?}", self)
})
}

/// Return `Some(..)` with the `DefId` of this `Def` if it has a id, else `None`.
pub fn opt_def_id(&self) -> Option<DefId> {
match *self {
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
@@ -284,6 +286,14 @@ impl Def {
}
}

/// Return the `DefId` of this `Def` if it represents a module.
pub fn mod_def_id(&self) -> Option<DefId> {
match *self {
Def::Mod(id) => Some(id),
_ => None,
}
}

/// A human readable name for the def kind ("function", "module", etc.).
pub fn kind_name(&self) -> &'static str {
match *self {
19 changes: 12 additions & 7 deletions src/librustc/middle/privacy.rs
Original file line number Diff line number Diff line change
@@ -11,16 +11,16 @@ use syntax::ast::NodeId;
// Accessibility levels, sorted in ascending order
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum AccessLevel {
// Superset of Reachable used to mark impl Trait items.
/// Superset of `AccessLevel::Reachable` used to mark impl Trait items.
ReachableFromImplTrait,
// Exported items + items participating in various kinds of public interfaces,
// but not directly nameable. For example, if function `fn f() -> T {...}` is
// public, then type `T` is reachable. Its values can be obtained by other crates
// even if the type itself is not nameable.
/// Exported items + items participating in various kinds of public interfaces,
/// but not directly nameable. For example, if function `fn f() -> T {...}` is
/// public, then type `T` is reachable. Its values can be obtained by other crates
/// even if the type itself is not nameable.
Reachable,
// Public items + items accessible to other crates with help of `pub use` re-exports
/// Public items + items accessible to other crates with help of `pub use` re-exports
Exported,
// Items accessible to other crates directly, without help of re-exports
/// Items accessible to other crates directly, without help of re-exports
Public,
}

@@ -31,12 +31,17 @@ pub struct AccessLevels<Id = NodeId> {
}

impl<Id: Hash + Eq> AccessLevels<Id> {
/// See `AccessLevel::Reachable`.
pub fn is_reachable(&self, id: Id) -> bool {
self.map.get(&id) >= Some(&AccessLevel::Reachable)
}

/// See `AccessLevel::Exported`.
pub fn is_exported(&self, id: Id) -> bool {
self.map.get(&id) >= Some(&AccessLevel::Exported)
}

/// See `AccessLevel::Public`.
pub fn is_public(&self, id: Id) -> bool {
self.map.get(&id) >= Some(&AccessLevel::Public)
}
47 changes: 45 additions & 2 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
@@ -436,6 +436,43 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
ev: self,
}
}


/// Given the path segments of a `ItemKind::Use`, then we need
/// to update the visibility of the intermediate use so that it isn't linted
/// by `unreachable_pub`.
///
/// This isn't trivial as `path.def` has the `DefId` of the eventual target
/// of the use statement not of the next intermediate use statement.
///
/// To do this, consider the last two segments of the path to our intermediate
/// use statement. We expect the penultimate segment to be a module and the
/// last segment to be the name of the item we are exporting. We can then
/// look at the items contained in the module for the use statement with that
/// name and update that item's visibility.
///
/// FIXME: This solution won't work with glob imports and doesn't respect
/// namespaces. See <https://github.com/rust-lang/rust/pull/57922#discussion_r251234202>.
fn update_visibility_of_intermediate_use_statements(&mut self, segments: &[hir::PathSegment]) {
if let Some([module, segment]) = segments.rchunks_exact(2).next() {
if let Some(item) = module.def
.and_then(|def| def.mod_def_id())
.and_then(|def_id| self.tcx.hir().as_local_node_id(def_id))
.map(|module_node_id| self.tcx.hir().expect_item(module_node_id))
{
if let hir::ItemKind::Mod(m) = &item.node {
for item_id in m.item_ids.as_ref() {
let item = self.tcx.hir().expect_item(item_id.id);
let def_id = self.tcx.hir().local_def_id(item_id.id);
if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { continue; }
if let hir::ItemKind::Use(..) = item.node {
self.update(item.id, Some(AccessLevel::Exported));
}
}
}
}
}
}
}

impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
@@ -522,8 +559,14 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
hir::ItemKind::ExternCrate(..) => {}
// All nested items are checked by `visit_item`.
hir::ItemKind::Mod(..) => {}
// Re-exports are handled in `visit_mod`.
hir::ItemKind::Use(..) => {}
// Re-exports are handled in `visit_mod`. However, in order to avoid looping over
// all of the items of a mod in `visit_mod` looking for use statements, we handle
// making sure that intermediate use statements have their visibilities updated here.
hir::ItemKind::Use(ref path, _) => {
if item_level.is_some() {
self.update_visibility_of_intermediate_use_statements(path.segments.as_ref());
}
}
// The interface is empty.
hir::ItemKind::GlobalAsm(..) => {}
hir::ItemKind::Existential(..) => {
80 changes: 70 additions & 10 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
@@ -15,11 +15,13 @@ use syntax::ast::{self, Ident};
use syntax::attr;
use syntax::errors::DiagnosticBuilder;
use syntax::ext::base::{self, Determinacy};
use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension};
use syntax::ext::base::{MacroKind, SyntaxExtension};
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
use syntax::ext::hygiene::{self, Mark};
use syntax::ext::tt::macro_rules;
use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue};
use syntax::feature_gate::{
feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES,
};
use syntax::symbol::{Symbol, keywords};
use syntax::visit::Visitor;
use syntax::util::lev_distance::find_best_match_for_name;
@@ -127,9 +129,9 @@ impl<'a> base::Resolver for Resolver<'a> {
mark
}

fn resolve_dollar_crates(&mut self, annotatable: &Annotatable) {
pub struct ResolveDollarCrates<'a, 'b: 'a> {
pub resolver: &'a mut Resolver<'b>,
fn resolve_dollar_crates(&mut self, fragment: &AstFragment) {
struct ResolveDollarCrates<'a, 'b: 'a> {
resolver: &'a mut Resolver<'b>
}
impl<'a> Visitor<'a> for ResolveDollarCrates<'a, '_> {
fn visit_ident(&mut self, ident: Ident) {
@@ -144,7 +146,7 @@ impl<'a> base::Resolver for Resolver<'a> {
fn visit_mac(&mut self, _: &ast::Mac) {}
}

annotatable.visit_with(&mut ResolveDollarCrates { resolver: self });
fragment.visit_with(&mut ResolveDollarCrates { resolver: self });
}

fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
@@ -310,15 +312,18 @@ impl<'a> Resolver<'a> {
if !features.rustc_attrs {
let msg = "unless otherwise specified, attributes with the prefix \
`rustc_` are reserved for internal compiler diagnostics";
feature_err(&self.session.parse_sess, "rustc_attrs", path.span,
GateIssue::Language, &msg).emit();
self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs");
}
} else if !features.custom_attribute {
let msg = format!("The attribute `{}` is currently unknown to the \
compiler and may have meaning added to it in the \
future", path);
feature_err(&self.session.parse_sess, "custom_attribute", path.span,
GateIssue::Language, &msg).emit();
self.report_unknown_attribute(
path.span,
&name,
&msg,
"custom_attribute",
);
}
}
} else {
@@ -339,6 +344,61 @@ impl<'a> Resolver<'a> {
Ok((def, self.get_macro(def)))
}

fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) {
let mut err = feature_err(
&self.session.parse_sess,
feature,
span,
GateIssue::Language,
&msg,
);

let features = self.session.features_untracked();

let attr_candidates = BUILTIN_ATTRIBUTES
.iter()
.filter_map(|(name, _, _, gate)| {
if name.starts_with("rustc_") && !features.rustc_attrs {
return None;
}

match gate {
AttributeGate::Gated(Stability::Unstable, ..)
if self.session.opts.unstable_features.is_nightly_build() =>
{
Some(name)
}
AttributeGate::Gated(Stability::Deprecated(..), ..) => Some(name),
AttributeGate::Ungated => Some(name),
_ => None,
}
})
.map(|name| Symbol::intern(name))
.chain(
// Add built-in macro attributes as well.
self.builtin_macros.iter().filter_map(|(name, binding)| {
match binding.macro_kind() {
Some(MacroKind::Attr) => Some(*name),
_ => None,
}
}),
)
.collect::<Vec<_>>();

let lev_suggestion = find_best_match_for_name(attr_candidates.iter(), &name, None);

if let Some(suggestion) = lev_suggestion {
err.span_suggestion(
span,
"a built-in attribute with a similar name exists",
suggestion.to_string(),
Applicability::MaybeIncorrect,
);
}

err.emit();
}

pub fn resolve_macro_to_def_inner(
&mut self,
path: &ast::Path,
5 changes: 1 addition & 4 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
@@ -537,11 +537,8 @@ impl<'a> Resolver<'a> {
primary_binding: &'a NameBinding<'a>, secondary_binding: &'a NameBinding<'a>)
-> &'a NameBinding<'a> {
self.arenas.alloc_name_binding(NameBinding {
kind: primary_binding.kind.clone(),
ambiguity: Some((secondary_binding, kind)),
vis: primary_binding.vis,
span: primary_binding.span,
expansion: primary_binding.expansion,
..primary_binding.clone()
})
}

4 changes: 0 additions & 4 deletions src/librustdoc/html/static/themes/dark.css
Original file line number Diff line number Diff line change
@@ -410,10 +410,6 @@ kbd {
color: #ccc;
}

.impl-items code {
background-color: rgba(0, 0, 0, 0);
}

#sidebar-toggle {
background-color: #565656;
}
4 changes: 0 additions & 4 deletions src/librustdoc/html/static/themes/light.css
Original file line number Diff line number Diff line change
@@ -405,10 +405,6 @@ kbd {
color: #999;
}

.impl-items code {
background-color: rgba(0, 0, 0, 0);
}

#sidebar-toggle {
background-color: #F1F1F1;
}
1 change: 1 addition & 0 deletions src/libstd/sys/mod.rs
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@ cfg_if! {
cfg_if! {
if #[cfg(any(unix, target_os = "redox"))] {
// On unix we'll document what's already available
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::ext as unix_ext;
} else if #[cfg(any(target_os = "cloudabi",
target_arch = "wasm32",
2 changes: 1 addition & 1 deletion src/libstd/thread/mod.rs
Original file line number Diff line number Diff line change
@@ -607,7 +607,7 @@ impl Builder {
pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
{
Builder::new().spawn(f).unwrap()
Builder::new().spawn(f).expect("failed to spawn thread")
}

/// Gets a handle to the thread that invokes it.
16 changes: 2 additions & 14 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@ use parse::token;
use ptr::P;
use smallvec::SmallVec;
use symbol::{keywords, Ident, Symbol};
use visit::Visitor;
use ThinVec;

use rustc_data_structures::fx::FxHashMap;
@@ -136,17 +135,6 @@ impl Annotatable {
_ => false,
}
}

pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
match self {
Annotatable::Item(item) => visitor.visit_item(item),
Annotatable::TraitItem(trait_item) => visitor.visit_trait_item(trait_item),
Annotatable::ImplItem(impl_item) => visitor.visit_impl_item(impl_item),
Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
Annotatable::Expr(expr) => visitor.visit_expr(expr),
}
}
}

// A more flexible ItemDecorator.
@@ -742,7 +730,7 @@ pub trait Resolver {
fn next_node_id(&mut self) -> ast::NodeId;
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;

fn resolve_dollar_crates(&mut self, annotatable: &Annotatable);
fn resolve_dollar_crates(&mut self, fragment: &AstFragment);
fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment,
derives: &[Mark]);
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>);
@@ -776,7 +764,7 @@ impl Resolver for DummyResolver {
fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }

fn resolve_dollar_crates(&mut self, _annotatable: &Annotatable) {}
fn resolve_dollar_crates(&mut self, _fragment: &AstFragment) {}
fn visit_ast_fragment_with_placeholders(&mut self, _invoc: Mark, _fragment: &AstFragment,
_derives: &[Mark]) {}
fn add_builtin(&mut self, _ident: ast::Ident, _ext: Lrc<SyntaxExtension>) {}
7 changes: 3 additions & 4 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
@@ -443,6 +443,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
/// prepares data for resolving paths of macro invocations.
fn collect_invocations(&mut self, fragment: AstFragment, derives: &[Mark])
-> (AstFragment, Vec<Invocation>) {
// Resolve `$crate`s in the fragment for pretty-printing.
self.cx.resolver.resolve_dollar_crates(&fragment);

let (fragment_with_placeholders, invocations) = {
let mut collector = InvocationCollector {
cfg: StripUnconfigured {
@@ -574,8 +577,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
Some(invoc.fragment_kind.expect_from_annotatables(items))
}
AttrProcMacro(ref mac, ..) => {
// Resolve `$crate`s in case we have to go though stringification.
self.cx.resolver.resolve_dollar_crates(&item);
self.gate_proc_macro_attr_item(attr.span, &item);
let item_tok = TokenTree::Token(DUMMY_SP, Token::interpolated(match item {
Annotatable::Item(item) => token::NtItem(item),
@@ -917,8 +918,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {

match *ext {
ProcMacroDerive(ref ext, ..) => {
// Resolve `$crate`s in case we have to go though stringification.
self.cx.resolver.resolve_dollar_crates(&item);
invoc.expansion_data.mark.set_expn_info(expn_info);
let span = span.with_ctxt(self.cx.backtrace());
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
18 changes: 18 additions & 0 deletions src/test/pretty/dollar-crate.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#![feature(prelude_import)]
#![no_std]
#[prelude_import]
use ::std::prelude::v1::*;
#[macro_use]
extern crate std;
// pretty-compare-only
// pretty-mode:expanded
// pp-exact:dollar-crate.pp

fn main() {
{
::std::io::_print(::std::fmt::Arguments::new_v1(&["rust\n"],
&match () {
() => [],
}));
};
}
7 changes: 7 additions & 0 deletions src/test/pretty/dollar-crate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// pretty-compare-only
// pretty-mode:expanded
// pp-exact:dollar-crate.pp

fn main() {
println!("rust");
}
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-49074.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0658]: The attribute `marco_use` is currently unknown to the compiler and
--> $DIR/issue-49074.rs:3:3
|
LL | #[marco_use] // typo
| ^^^^^^^^^
| ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

18 changes: 18 additions & 0 deletions src/test/ui/issues/issue-57410-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// compile-pass

// Originally from #53925.
// Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`.

#![deny(unreachable_pub)]

mod foo {
mod bar {
pub struct Bar;
}

pub use self::bar::Bar;
}

pub use foo::Bar;

fn main() {}
17 changes: 17 additions & 0 deletions src/test/ui/issues/issue-57410.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// compile-pass

// Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`.

#![deny(unreachable_pub)]

mod m {
mod imp {
pub fn f() {}
}

pub use self::imp::f;
}

pub use self::m::f;

fn main() {}
2 changes: 1 addition & 1 deletion src/test/ui/macros/macro-reexport-removed.stderr
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ error[E0658]: The attribute `macro_reexport` is currently unknown to the compile
--> $DIR/macro-reexport-removed.rs:5:3
|
LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

2 changes: 1 addition & 1 deletion src/test/ui/proc-macro/derive-still-gated.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0658]: The attribute `derive_A` is currently unknown to the compiler and
--> $DIR/derive-still-gated.rs:8:3
|
LL | #[derive_A] //~ ERROR attribute `derive_A` is currently unknown
| ^^^^^^^^
| ^^^^^^^^ help: a built-in attribute with a similar name exists: `derive`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

13 changes: 13 additions & 0 deletions src/test/ui/suggestions/attribute-typos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#[deprcated] //~ ERROR E0658
fn foo() {} //~| HELP a built-in attribute with a similar name exists
//~| SUGGESTION deprecated
//~| HELP add #![feature(custom_attribute)] to the crate attributes to enable

#[tests] //~ ERROR E0658
fn bar() {} //~| HELP a built-in attribute with a similar name exists
//~| SUGGESTION test
//~| HELP add #![feature(custom_attribute)] to the crate attributes to enable

#[rustc_err] //~ ERROR E0658
fn main() {} //~| HELP add #![feature(rustc_attrs)] to the crate attributes to enable
// don't suggest rustc attributes
27 changes: 27 additions & 0 deletions src/test/ui/suggestions/attribute-typos.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642)
--> $DIR/attribute-typos.rs:11:3
|
LL | #[rustc_err] //~ ERROR E0658
| ^^^^^^^^^
|
= help: add #![feature(rustc_attrs)] to the crate attributes to enable

error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/attribute-typos.rs:6:3
|
LL | #[tests] //~ ERROR E0658
| ^^^^^ help: a built-in attribute with a similar name exists: `test`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error[E0658]: The attribute `deprcated` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/attribute-typos.rs:1:3
|
LL | #[deprcated] //~ ERROR E0658
| ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.