Auto merge of #70062 - Centril:rollup-synwle8, r=Centril

Rollup of 7 pull requests

Successful merges:

 - #69811 (resolve: Print import chains on privacy errors)
 - #69870 (expand: Implement something similar to `#[cfg(accessible(path))]`)
 - #69881 (VariantSizeDifferences: bail on SizeOverflow)
 - #70000 (resolve: Fix regression in resolution of raw keywords in paths)
 - #70029 (Bump the bootstrap compiler)
 - #70046 (Use sublice patterns to avoid computing the len)
 - #70049 (Fiddle `ParamEnv` through to a place that used to use `ParamEnv::empty` in a buggy manner)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-03-17 02:06:21 +00:00
commit 5e9ebf4da3
52 changed files with 679 additions and 271 deletions

View File

@ -725,7 +725,7 @@ impl<'a> Builder<'a> {
self.clear_if_dirty(&my_out, &rustdoc);
}
cargo.env("CARGO_TARGET_DIR", &out_dir).arg(cmd).arg("-Zconfig-profile");
cargo.env("CARGO_TARGET_DIR", &out_dir).arg(cmd);
let profile_var = |name: &str| {
let profile = if self.config.rust_optimize { "RELEASE" } else { "DEV" };
@ -847,13 +847,7 @@ impl<'a> Builder<'a> {
rustflags.arg("-Zforce-unstable-if-unmarked");
}
// cfg(bootstrap): the flag was renamed from `-Zexternal-macro-backtrace`
// to `-Zmacro-backtrace`, keep only the latter after beta promotion.
if stage == 0 {
rustflags.arg("-Zexternal-macro-backtrace");
} else {
rustflags.arg("-Zmacro-backtrace");
}
rustflags.arg("-Zmacro-backtrace");
let want_rustdoc = self.doc_tests != DocTests::No;

View File

@ -13,7 +13,7 @@ use build_helper::output;
use crate::Build;
// The version number
pub const CFG_RELEASE_NUM: &str = "1.43.0";
pub const CFG_RELEASE_NUM: &str = "1.44.0";
pub struct GitInfo {
inner: Option<Info>,

View File

@ -1105,29 +1105,6 @@ impl<T: ?Sized> AsMut<T> for Box<T> {
#[stable(feature = "pin", since = "1.33.0")]
impl<T: ?Sized> Unpin for Box<T> {}
#[cfg(bootstrap)]
#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator + Unpin> Generator for Box<G> {
type Yield = G::Yield;
type Return = G::Return;
fn resume(mut self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return> {
G::resume(Pin::new(&mut *self))
}
}
#[cfg(bootstrap)]
#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator> Generator for Pin<Box<G>> {
type Yield = G::Yield;
type Return = G::Return;
fn resume(mut self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return> {
G::resume((*self).as_mut())
}
}
#[cfg(not(bootstrap))]
#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for Box<G> {
type Yield = G::Yield;
@ -1138,7 +1115,6 @@ impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for Box<G> {
}
}
#[cfg(not(bootstrap))]
#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<Box<G>> {
type Yield = G::Yield;

View File

@ -1569,7 +1569,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
#[lang = "unsafe_cell"]
#[stable(feature = "rust1", since = "1.0.0")]
#[repr(transparent)]
#[cfg_attr(not(bootstrap), repr(no_niche))] // rust-lang/rust#68303.
#[repr(no_niche)] // rust-lang/rust#68303.
pub struct UnsafeCell<T: ?Sized> {
value: T,
}

View File

@ -140,7 +140,7 @@
#![feature(associated_type_bounds)]
#![feature(const_type_id)]
#![feature(const_caller_location)]
#![cfg_attr(not(bootstrap), feature(no_niche))] // rust-lang/rust#68303
#![feature(no_niche)] // rust-lang/rust#68303
#[prelude_import]
#[allow(unused)]

View File

@ -1404,6 +1404,18 @@ pub(crate) mod builtin {
/* compiler built-in */
}
/// Keeps the item it's applied to if the passed path is accessible, and removes it otherwise.
#[cfg(not(bootstrap))]
#[unstable(
feature = "cfg_accessible",
issue = "64797",
reason = "`cfg_accessible` is not fully implemented"
)]
#[rustc_builtin_macro]
pub macro cfg_accessible($item:item) {
/* compiler built-in */
}
/// Unstable implementation detail of the `rustc` compiler, do not use.
#[rustc_builtin_macro]
#[stable(feature = "rust1", since = "1.0.0")]

View File

@ -67,7 +67,7 @@ pub enum GeneratorState<Y, R> {
#[lang = "generator"]
#[unstable(feature = "generator_trait", issue = "43122")]
#[fundamental]
pub trait Generator<#[cfg(not(bootstrap))] R = ()> {
pub trait Generator<R = ()> {
/// The type of value this generator yields.
///
/// This associated type corresponds to the `yield` expression and the
@ -110,35 +110,9 @@ pub trait Generator<#[cfg(not(bootstrap))] R = ()> {
/// been returned previously. While generator literals in the language are
/// guaranteed to panic on resuming after `Complete`, this is not guaranteed
/// for all implementations of the `Generator` trait.
fn resume(
self: Pin<&mut Self>,
#[cfg(not(bootstrap))] arg: R,
) -> GeneratorState<Self::Yield, Self::Return>;
fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return>;
}
#[cfg(bootstrap)]
#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator> Generator for Pin<&mut G> {
type Yield = G::Yield;
type Return = G::Return;
fn resume(mut self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return> {
G::resume((*self).as_mut())
}
}
#[cfg(bootstrap)]
#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator + Unpin> Generator for &mut G {
type Yield = G::Yield;
type Return = G::Return;
fn resume(mut self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return> {
G::resume(Pin::new(&mut *self))
}
}
#[cfg(not(bootstrap))]
#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<&mut G> {
type Yield = G::Yield;
@ -149,7 +123,6 @@ impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<&mut G> {
}
}
#[cfg(not(bootstrap))]
#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for &mut G {
type Yield = G::Yield;

View File

@ -67,3 +67,12 @@ pub use crate::{
pub use crate::macros::builtin::{
bench, global_allocator, test, test_case, RustcDecodable, RustcEncodable,
};
#[cfg(not(bootstrap))]
#[unstable(
feature = "cfg_accessible",
issue = "64797",
reason = "`cfg_accessible` is not fully implemented"
)]
#[doc(no_inline)]
pub use crate::macros::builtin::cfg_accessible;

View File

@ -90,30 +90,46 @@ impl<'tcx> TyCtxt<'tcx> {
/// ```
/// This code should only compile in modules where the uninhabitedness of Foo is
/// visible.
pub fn is_ty_uninhabited_from(self, module: DefId, ty: Ty<'tcx>) -> bool {
pub fn is_ty_uninhabited_from(
self,
module: DefId,
ty: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> bool {
// To check whether this type is uninhabited at all (not just from the
// given node), you could check whether the forest is empty.
// ```
// forest.is_empty()
// ```
ty.uninhabited_from(self).contains(self, module)
ty.uninhabited_from(self, param_env).contains(self, module)
}
pub fn is_ty_uninhabited_from_any_module(self, ty: Ty<'tcx>) -> bool {
!ty.uninhabited_from(self).is_empty()
pub fn is_ty_uninhabited_from_any_module(
self,
ty: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> bool {
!ty.uninhabited_from(self, param_env).is_empty()
}
}
impl<'tcx> AdtDef {
/// Calculates the forest of `DefId`s from which this ADT is visibly uninhabited.
fn uninhabited_from(&self, tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>) -> DefIdForest {
fn uninhabited_from(
&self,
tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest {
// Non-exhaustive ADTs from other crates are always considered inhabited.
if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
DefIdForest::empty()
} else {
DefIdForest::intersection(
tcx,
self.variants.iter().map(|v| v.uninhabited_from(tcx, substs, self.adt_kind())),
self.variants
.iter()
.map(|v| v.uninhabited_from(tcx, substs, self.adt_kind(), param_env)),
)
}
}
@ -126,6 +142,7 @@ impl<'tcx> VariantDef {
tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>,
adt_kind: AdtKind,
param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest {
let is_enum = match adt_kind {
// For now, `union`s are never considered uninhabited.
@ -140,7 +157,7 @@ impl<'tcx> VariantDef {
} else {
DefIdForest::union(
tcx,
self.fields.iter().map(|f| f.uninhabited_from(tcx, substs, is_enum)),
self.fields.iter().map(|f| f.uninhabited_from(tcx, substs, is_enum, param_env)),
)
}
}
@ -153,8 +170,9 @@ impl<'tcx> FieldDef {
tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>,
is_enum: bool,
param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest {
let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx);
let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env);
// FIXME(canndrew): Currently enum fields are (incorrectly) stored with
// `Visibility::Invisible` so we need to override `self.vis` if we're
// dealing with an enum.
@ -176,20 +194,21 @@ impl<'tcx> FieldDef {
impl<'tcx> TyS<'tcx> {
/// Calculates the forest of `DefId`s from which this type is visibly uninhabited.
fn uninhabited_from(&self, tcx: TyCtxt<'tcx>) -> DefIdForest {
fn uninhabited_from(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> DefIdForest {
match self.kind {
Adt(def, substs) => def.uninhabited_from(tcx, substs),
Adt(def, substs) => def.uninhabited_from(tcx, substs, param_env),
Never => DefIdForest::full(tcx),
Tuple(ref tys) => {
DefIdForest::union(tcx, tys.iter().map(|ty| ty.expect_ty().uninhabited_from(tcx)))
}
Tuple(ref tys) => DefIdForest::union(
tcx,
tys.iter().map(|ty| ty.expect_ty().uninhabited_from(tcx, param_env)),
),
Array(ty, len) => match len.try_eval_usize(tcx, ty::ParamEnv::empty()) {
Array(ty, len) => match len.try_eval_usize(tcx, param_env) {
// If the array is definitely non-empty, it's uninhabited if
// the type of its elements is uninhabited.
Some(n) if n != 0 => ty.uninhabited_from(tcx),
Some(n) if n != 0 => ty.uninhabited_from(tcx, param_env),
_ => DefIdForest::empty(),
},

View File

@ -0,0 +1,54 @@
//! Implementation of the `#[cfg_accessible(path)]` attribute macro.
use rustc_ast::ast;
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
use rustc_feature::AttributeTemplate;
use rustc_parse::validate_attr;
use rustc_span::symbol::sym;
use rustc_span::Span;
crate struct Expander;
fn validate_input<'a>(ecx: &mut ExtCtxt<'_>, mi: &'a ast::MetaItem) -> Option<&'a ast::Path> {
match mi.meta_item_list() {
None => {}
Some([]) => ecx.span_err(mi.span, "`cfg_accessible` path is not specified"),
Some([_, .., l]) => ecx.span_err(l.span(), "multiple `cfg_accessible` paths are specified"),
Some([nmi]) => match nmi.meta_item() {
None => ecx.span_err(nmi.span(), "`cfg_accessible` path cannot be a literal"),
Some(mi) => {
if !mi.is_word() {
ecx.span_err(mi.span, "`cfg_accessible` path cannot accept arguments");
}
return Some(&mi.path);
}
},
}
None
}
impl MultiItemModifier for Expander {
fn expand(
&self,
ecx: &mut ExtCtxt<'_>,
_span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
let template = AttributeTemplate { list: Some("path"), ..Default::default() };
let attr = &ecx.attribute(meta_item.clone());
validate_attr::check_builtin_attribute(ecx.parse_sess, attr, sym::cfg_accessible, template);
let path = match validate_input(ecx, meta_item) {
Some(path) => path,
None => return ExpandResult::Ready(Vec::new()),
};
let failure_msg = "cannot determine whether the path is accessible or not";
match ecx.resolver.cfg_accessible(ecx.current_expansion.id, path) {
Ok(true) => ExpandResult::Ready(vec![item]),
Ok(false) => ExpandResult::Ready(Vec::new()),
Err(_) => ExpandResult::Retry(item, failure_msg.into()),
}
}
}

View File

@ -2,7 +2,7 @@
use rustc_ast::ast::{self, ItemKind, MetaItem};
use rustc_ast::ptr::P;
use rustc_expand::base::{Annotatable, ExtCtxt, MultiItemModifier};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
@ -48,13 +48,13 @@ impl MultiItemModifier for BuiltinDerive {
span: Span,
meta_item: &MetaItem,
item: Annotatable,
) -> Vec<Annotatable> {
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
// FIXME: Built-in derives often forget to give spans contexts,
// so we are doing it here in a centralized way.
let span = ecx.with_def_site_ctxt(span);
let mut items = Vec::new();
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
items
ExpandResult::Ready(items)
}
}

View File

@ -22,6 +22,7 @@ use rustc_span::symbol::sym;
mod asm;
mod assert;
mod cfg;
mod cfg_accessible;
mod compile_error;
mod concat;
mod concat_idents;
@ -85,6 +86,7 @@ pub fn register_builtin_macros(resolver: &mut dyn Resolver, edition: Edition) {
register_attr! {
bench: test::expand_bench,
cfg_accessible: cfg_accessible::Expander,
global_allocator: global_allocator::expand,
test: test::expand_test,
test_case: test::expand_test_case,

View File

@ -6,7 +6,7 @@ use rustc_span::Symbol;
pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) {
// All the built-in macro attributes are "words" at the moment.
let template = AttributeTemplate::only_word();
let template = AttributeTemplate { word: true, ..Default::default() };
let attr = ecx.attribute(meta_item.clone());
validate_attr::check_builtin_attribute(ecx.parse_sess, &attr, name, template);
}

View File

@ -25,22 +25,6 @@ pub struct PinnedGenerator<I, A, R> {
}
impl<I, A, R> PinnedGenerator<I, A, R> {
#[cfg(bootstrap)]
pub fn new<T: Generator<Yield = YieldType<I, A>, Return = R> + 'static>(
generator: T,
) -> (I, Self) {
let mut result = PinnedGenerator { generator: Box::pin(generator) };
// Run it to the first yield to set it up
let init = match Pin::new(&mut result.generator).resume() {
GeneratorState::Yielded(YieldType::Initial(y)) => y,
_ => panic!(),
};
(init, result)
}
#[cfg(not(bootstrap))]
pub fn new<T: Generator<Yield = YieldType<I, A>, Return = R> + 'static>(
generator: T,
) -> (I, Self) {
@ -55,19 +39,6 @@ impl<I, A, R> PinnedGenerator<I, A, R> {
(init, result)
}
#[cfg(bootstrap)]
pub unsafe fn access(&mut self, closure: *mut dyn FnMut()) {
BOX_REGION_ARG.with(|i| {
i.set(Action::Access(AccessAction(closure)));
});
// Call the generator, which in turn will call the closure in BOX_REGION_ARG
if let GeneratorState::Complete(_) = Pin::new(&mut self.generator).resume() {
panic!()
}
}
#[cfg(not(bootstrap))]
pub unsafe fn access(&mut self, closure: *mut dyn FnMut()) {
BOX_REGION_ARG.with(|i| {
i.set(Action::Access(AccessAction(closure)));
@ -79,16 +50,6 @@ impl<I, A, R> PinnedGenerator<I, A, R> {
}
}
#[cfg(bootstrap)]
pub fn complete(&mut self) -> R {
// Tell the generator we want it to complete, consuming it and yielding a result
BOX_REGION_ARG.with(|i| i.set(Action::Complete));
let result = Pin::new(&mut self.generator).resume();
if let GeneratorState::Complete(r) = result { r } else { panic!() }
}
#[cfg(not(bootstrap))]
pub fn complete(&mut self) -> R {
// Tell the generator we want it to complete, consuming it and yielding a result
BOX_REGION_ARG.with(|i| i.set(Action::Complete));

View File

@ -258,8 +258,17 @@ impl Annotatable {
}
}
// `meta_item` is the annotation, and `item` is the item being modified.
// FIXME Decorators should follow the same pattern too.
/// Result of an expansion that may need to be retried.
/// Consider using this for non-`MultiItemModifier` expanders as well.
pub enum ExpandResult<T, U> {
/// Expansion produced a result (possibly dummy).
Ready(T),
/// Expansion could not produce a result and needs to be retried.
/// The string is an explanation that will be printed if we are stuck in an infinite retry loop.
Retry(U, String),
}
// `meta_item` is the attribute, and `item` is the item being modified.
pub trait MultiItemModifier {
fn expand(
&self,
@ -267,13 +276,12 @@ pub trait MultiItemModifier {
span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
) -> Vec<Annotatable>;
) -> ExpandResult<Vec<Annotatable>, Annotatable>;
}
impl<F, T> MultiItemModifier for F
impl<F> MultiItemModifier for F
where
F: Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, Annotatable) -> T,
T: Into<Vec<Annotatable>>,
F: Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, Annotatable) -> Vec<Annotatable>,
{
fn expand(
&self,
@ -281,14 +289,8 @@ where
span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
) -> Vec<Annotatable> {
(*self)(ecx, span, meta_item, item).into()
}
}
impl Into<Vec<Annotatable>> for Annotatable {
fn into(self) -> Vec<Annotatable> {
vec![self]
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
ExpandResult::Ready(self(ecx, span, meta_item, item))
}
}
@ -895,6 +897,7 @@ pub trait Resolver {
fn has_derive_copy(&self, expn_id: ExpnId) -> bool;
fn add_derive_copy(&mut self, expn_id: ExpnId);
fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result<bool, Indeterminate>;
}
#[derive(Clone)]

View File

@ -408,7 +408,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
let mut undetermined_invocations = Vec::new();
let (mut progress, mut force) = (false, !self.monotonic);
loop {
let invoc = if let Some(invoc) = invocations.pop() {
let (invoc, res) = if let Some(invoc) = invocations.pop() {
invoc
} else {
self.resolve_imports();
@ -420,30 +420,51 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
continue;
};
let eager_expansion_root =
if self.monotonic { invoc.expansion_data.id } else { orig_expansion_data.id };
let res = match self.cx.resolver.resolve_macro_invocation(
&invoc,
eager_expansion_root,
force,
) {
Ok(res) => res,
Err(Indeterminate) => {
undetermined_invocations.push(invoc);
continue;
let res = match res {
Some(res) => res,
None => {
let eager_expansion_root = if self.monotonic {
invoc.expansion_data.id
} else {
orig_expansion_data.id
};
match self.cx.resolver.resolve_macro_invocation(
&invoc,
eager_expansion_root,
force,
) {
Ok(res) => res,
Err(Indeterminate) => {
// Cannot resolve, will retry this invocation later.
undetermined_invocations.push((invoc, None));
continue;
}
}
}
};
progress = true;
let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
self.cx.current_expansion = invoc.expansion_data.clone();
// FIXME(jseyfried): Refactor out the following logic
let (expanded_fragment, new_invocations) = match res {
InvocationRes::Single(ext) => {
let fragment = self.expand_invoc(invoc, &ext.kind);
self.collect_invocations(fragment, &[])
}
InvocationRes::Single(ext) => match self.expand_invoc(invoc, &ext.kind) {
ExpandResult::Ready(fragment) => self.collect_invocations(fragment, &[]),
ExpandResult::Retry(invoc, explanation) => {
if force {
// We are stuck, stop retrying and produce a dummy fragment.
let span = invoc.span();
self.cx.span_err(span, &explanation);
let fragment = invoc.fragment_kind.dummy(span);
self.collect_invocations(fragment, &[])
} else {
// Cannot expand, will retry this invocation later.
undetermined_invocations
.push((invoc, Some(InvocationRes::Single(ext))));
continue;
}
}
},
InvocationRes::DeriveContainer(_exts) => {
// FIXME: Consider using the derive resolutions (`_exts`) immediately,
// instead of enqueuing the derives to be resolved again later.
@ -463,14 +484,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
for path in derives {
let expn_id = ExpnId::fresh(None);
derive_placeholders.push(NodeId::placeholder_from_expn_id(expn_id));
invocations.push(Invocation {
kind: InvocationKind::Derive { path, item: item.clone() },
fragment_kind: invoc.fragment_kind,
expansion_data: ExpansionData {
id: expn_id,
..invoc.expansion_data.clone()
invocations.push((
Invocation {
kind: InvocationKind::Derive { path, item: item.clone() },
fragment_kind: invoc.fragment_kind,
expansion_data: ExpansionData {
id: expn_id,
..invoc.expansion_data.clone()
},
},
});
None,
));
}
let fragment =
invoc.fragment_kind.expect_from_annotatables(::std::iter::once(item));
@ -478,6 +502,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
};
progress = true;
if expanded_fragments.len() < depth {
expanded_fragments.push(Vec::new());
}
@ -535,7 +560,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
&mut self,
mut fragment: AstFragment,
extra_placeholders: &[NodeId],
) -> (AstFragment, Vec<Invocation>) {
) -> (AstFragment, Vec<(Invocation, Option<InvocationRes>)>) {
// Resolve `$crate`s in the fragment for pretty-printing.
self.cx.resolver.resolve_dollar_crates();
@ -635,13 +660,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
self.cx.trace_macros_diag();
}
fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtensionKind) -> AstFragment {
fn expand_invoc(
&mut self,
invoc: Invocation,
ext: &SyntaxExtensionKind,
) -> ExpandResult<AstFragment, Invocation> {
if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit {
self.error_recursion_limit_reached();
}
let (fragment_kind, span) = (invoc.fragment_kind, invoc.span());
match invoc.kind {
ExpandResult::Ready(match invoc.kind {
InvocationKind::Bang { mac, .. } => match ext {
SyntaxExtensionKind::Bang(expander) => {
self.gate_proc_macro_expansion_kind(span, fragment_kind);
@ -663,7 +692,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
_ => unreachable!(),
},
InvocationKind::Attr { attr, mut item, .. } => match ext {
InvocationKind::Attr { attr, mut item, derives, after_derive } => match ext {
SyntaxExtensionKind::Attr(expander) => {
self.gate_proc_macro_input(&item);
self.gate_proc_macro_attr_item(span, &item);
@ -679,8 +708,25 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
SyntaxExtensionKind::LegacyAttr(expander) => {
match validate_attr::parse_meta(self.cx.parse_sess, &attr) {
Ok(meta) => {
let item = expander.expand(self.cx, span, &meta, item);
fragment_kind.expect_from_annotatables(item)
let items = match expander.expand(self.cx, span, &meta, item) {
ExpandResult::Ready(items) => items,
ExpandResult::Retry(item, explanation) => {
// Reassemble the original invocation for retrying.
return ExpandResult::Retry(
Invocation {
kind: InvocationKind::Attr {
attr,
item,
derives,
after_derive,
},
..invoc
},
explanation,
);
}
};
fragment_kind.expect_from_annotatables(items)
}
Err(mut err) => {
err.emit();
@ -702,19 +748,31 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
SyntaxExtensionKind::Derive(expander)
| SyntaxExtensionKind::LegacyDerive(expander) => {
if !item.derive_allowed() {
return fragment_kind.dummy(span);
return ExpandResult::Ready(fragment_kind.dummy(span));
}
if let SyntaxExtensionKind::Derive(..) = ext {
self.gate_proc_macro_input(&item);
}
let meta = ast::MetaItem { kind: ast::MetaItemKind::Word, span, path };
let items = expander.expand(self.cx, span, &meta, item);
let items = match expander.expand(self.cx, span, &meta, item) {
ExpandResult::Ready(items) => items,
ExpandResult::Retry(item, explanation) => {
// Reassemble the original invocation for retrying.
return ExpandResult::Retry(
Invocation {
kind: InvocationKind::Derive { path: meta.path, item },
..invoc
},
explanation,
);
}
};
fragment_kind.expect_from_annotatables(items)
}
_ => unreachable!(),
},
InvocationKind::DeriveContainer { .. } => unreachable!(),
}
})
}
fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
@ -933,7 +991,7 @@ pub fn ensure_complete_parse<'a>(
struct InvocationCollector<'a, 'b> {
cx: &'a mut ExtCtxt<'b>,
cfg: StripUnconfigured<'a>,
invocations: Vec<Invocation>,
invocations: Vec<(Invocation, Option<InvocationRes>)>,
monotonic: bool,
}
@ -955,15 +1013,18 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
};
let expn_id = ExpnId::fresh(expn_data);
let vis = kind.placeholder_visibility();
self.invocations.push(Invocation {
kind,
fragment_kind,
expansion_data: ExpansionData {
id: expn_id,
depth: self.cx.current_expansion.depth + 1,
..self.cx.current_expansion.clone()
self.invocations.push((
Invocation {
kind,
fragment_kind,
expansion_data: ExpansionData {
id: expn_id,
depth: self.cx.current_expansion.depth + 1,
..self.cx.current_expansion.clone()
},
},
});
None,
));
placeholder(fragment_kind, NodeId::placeholder_from_expn_id(expn_id), vis)
}

View File

@ -79,7 +79,7 @@ impl MultiItemModifier for ProcMacroDerive {
span: Span,
_meta_item: &ast::MetaItem,
item: Annotatable,
) -> Vec<Annotatable> {
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
let item = match item {
Annotatable::Arm(..)
| Annotatable::Field(..)
@ -99,7 +99,7 @@ impl MultiItemModifier for ProcMacroDerive {
"proc-macro derives may only be \
applied to a struct, enum, or union",
);
return Vec::new();
return ExpandResult::Ready(Vec::new());
}
};
match item.kind {
@ -110,7 +110,7 @@ impl MultiItemModifier for ProcMacroDerive {
"proc-macro derives may only be \
applied to a struct, enum, or union",
);
return Vec::new();
return ExpandResult::Ready(Vec::new());
}
}
@ -158,7 +158,7 @@ impl MultiItemModifier for ProcMacroDerive {
FatalError.raise();
}
items
ExpandResult::Ready(items)
}
}

View File

@ -85,19 +85,13 @@ impl AttributeGate {
/// A template that the attribute input must match.
/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now.
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Default)]
pub struct AttributeTemplate {
pub word: bool,
pub list: Option<&'static str>,
pub name_value_str: Option<&'static str>,
}
impl AttributeTemplate {
pub fn only_word() -> Self {
Self { word: true, list: None, name_value_str: None }
}
}
/// A convenience macro for constructing attribute templates.
/// E.g., `template!(Word, List: "description")` means that the attribute
/// supports forms `#[attr]` and `#[attr(description)]`.

View File

@ -1032,10 +1032,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
let ty = cx.tcx.erase_regions(&t);
let layout = match cx.layout_of(ty) {
Ok(layout) => layout,
Err(ty::layout::LayoutError::Unknown(_)) => return,
Err(err @ ty::layout::LayoutError::SizeOverflow(_)) => {
bug!("failed to get layout for `{}`: {}", t, err);
}
Err(ty::layout::LayoutError::Unknown(_))
| Err(ty::layout::LayoutError::SizeOverflow(_)) => return,
};
let (variants, tag) = match layout.variants {
layout::Variants::Multiple {

View File

@ -124,7 +124,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
descr_post: &str,
plural_len: usize,
) -> bool {
if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(cx.tcx.parent_module(expr.hir_id), ty)
if ty.is_unit()
|| cx.tcx.is_ty_uninhabited_from(
cx.tcx.parent_module(expr.hir_id),
ty,
cx.param_env,
)
{
return true;
}

View File

@ -209,7 +209,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
i == variant_index || {
self.hir.tcx().features().exhaustive_patterns
&& !v
.uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind())
.uninhabited_from(
self.hir.tcx(),
substs,
adt_def.adt_kind(),
self.hir.param_env,
)
.is_empty()
}
}) && (adt_def.did.is_local()

View File

@ -598,7 +598,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
if self.tcx.features().exhaustive_patterns {
self.tcx.is_ty_uninhabited_from(self.module, ty)
self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env)
} else {
false
}
@ -1267,7 +1267,7 @@ fn all_constructors<'a, 'tcx>(
def.variants
.iter()
.filter(|v| {
!v.uninhabited_from(cx.tcx, substs, def.adt_kind())
!v.uninhabited_from(cx.tcx, substs, def.adt_kind(), cx.param_env)
.contains(cx.tcx, cx.module)
})
.map(|v| Variant(v.def_id))

View File

@ -398,7 +398,7 @@ fn visit_fn<'tcx>(
intravisit::walk_fn(&mut fn_maps, fk, decl, body_id, sp, id);
// compute liveness
let mut lsets = Liveness::new(&mut fn_maps, body_id);
let mut lsets = Liveness::new(&mut fn_maps, def_id);
let entry_ln = lsets.compute(&body.value);
// check for various error conditions
@ -658,6 +658,7 @@ const ACC_USE: u32 = 4;
struct Liveness<'a, 'tcx> {
ir: &'a mut IrMaps<'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
param_env: ty::ParamEnv<'tcx>,
s: Specials,
successors: Vec<LiveNode>,
rwu_table: RWUTable,
@ -670,7 +671,7 @@ struct Liveness<'a, 'tcx> {
}
impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn new(ir: &'a mut IrMaps<'tcx>, body: hir::BodyId) -> Liveness<'a, 'tcx> {
fn new(ir: &'a mut IrMaps<'tcx>, def_id: DefId) -> Liveness<'a, 'tcx> {
// Special nodes and variables:
// - exit_ln represents the end of the fn, either by return or panic
// - implicit_ret_var is a pseudo-variable that represents
@ -681,7 +682,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
clean_exit_var: ir.add_variable(CleanExit),
};
let tables = ir.tcx.body_tables(body);
let tables = ir.tcx.typeck_tables_of(def_id);
let param_env = ir.tcx.param_env(def_id);
let num_live_nodes = ir.num_live_nodes;
let num_vars = ir.num_vars;
@ -689,6 +691,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
Liveness {
ir,
tables,
param_env,
s: specials,
successors: vec![invalid_node(); num_live_nodes],
rwu_table: RWUTable::new(num_live_nodes * num_vars),
@ -1126,7 +1129,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hir::ExprKind::Call(ref f, ref args) => {
let m = self.ir.tcx.parent_module(expr.hir_id);
let succ = if self.ir.tcx.is_ty_uninhabited_from(m, self.tables.expr_ty(expr)) {
let succ = if self.ir.tcx.is_ty_uninhabited_from(
m,
self.tables.expr_ty(expr),
self.param_env,
) {
self.s.exit_ln
} else {
succ
@ -1137,7 +1144,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hir::ExprKind::MethodCall(.., ref args) => {
let m = self.ir.tcx.parent_module(expr.hir_id);
let succ = if self.ir.tcx.is_ty_uninhabited_from(m, self.tables.expr_ty(expr)) {
let succ = if self.ir.tcx.is_ty_uninhabited_from(
m,
self.tables.expr_ty(expr),
self.param_env,
) {
self.s.exit_ln
} else {
succ

View File

@ -1,4 +1,5 @@
use std::cmp::Reverse;
use std::ptr;
use log::debug;
use rustc::bug;
@ -918,50 +919,81 @@ impl<'a> Resolver<'a> {
err.emit();
}
crate fn report_privacy_error(&self, privacy_error: &PrivacyError<'_>) {
let PrivacyError { ident, binding, .. } = *privacy_error;
let session = &self.session;
let mk_struct_span_error = |is_constructor| {
let mut descr = binding.res().descr().to_string();
if is_constructor {
descr += " constructor";
}
if binding.is_import() {
descr += " import";
}
let mut err =
struct_span_err!(session, ident.span, E0603, "{} `{}` is private", descr, ident);
err.span_label(ident.span, &format!("this {} is private", descr));
err.span_note(
session.source_map().def_span(binding.span),
&format!("the {} `{}` is defined here", descr, ident),
);
err
};
let mut err = if let NameBindingKind::Res(
/// If the binding refers to a tuple struct constructor with fields,
/// returns the span of its fields.
fn ctor_fields_span(&self, binding: &NameBinding<'_>) -> Option<Span> {
if let NameBindingKind::Res(
Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id),
_,
) = binding.kind
{
let def_id = (&*self).parent(ctor_def_id).expect("no parent for a constructor");
if let Some(fields) = self.field_names.get(&def_id) {
let mut err = mk_struct_span_error(true);
let first_field = fields.first().expect("empty field list in the map");
err.span_label(
fields.iter().fold(first_field.span, |acc, field| acc.to(field.span)),
"a constructor is private if any of the fields is private",
);
err
} else {
mk_struct_span_error(false)
return Some(fields.iter().fold(first_field.span, |acc, field| acc.to(field.span)));
}
} else {
mk_struct_span_error(false)
};
}
None
}
crate fn report_privacy_error(&self, privacy_error: &PrivacyError<'_>) {
let PrivacyError { ident, binding, .. } = *privacy_error;
let res = binding.res();
let ctor_fields_span = self.ctor_fields_span(binding);
let plain_descr = res.descr().to_string();
let nonimport_descr =
if ctor_fields_span.is_some() { plain_descr + " constructor" } else { plain_descr };
let import_descr = nonimport_descr.clone() + " import";
let get_descr =
|b: &NameBinding<'_>| if b.is_import() { &import_descr } else { &nonimport_descr };
// Print the primary message.
let descr = get_descr(binding);
let mut err =
struct_span_err!(self.session, ident.span, E0603, "{} `{}` is private", descr, ident);
err.span_label(ident.span, &format!("this {} is private", descr));
if let Some(span) = ctor_fields_span {
err.span_label(span, "a constructor is private if any of the fields is private");
}
// Print the whole import chain to make it easier to see what happens.
let first_binding = binding;
let mut next_binding = Some(binding);
let mut next_ident = ident;
while let Some(binding) = next_binding {
let name = next_ident;
next_binding = match binding.kind {
_ if res == Res::Err => None,
NameBindingKind::Import { binding, import, .. } => match import.kind {
_ if binding.span.is_dummy() => None,
ImportKind::Single { source, .. } => {
next_ident = source;
Some(binding)
}
ImportKind::Glob { .. } | ImportKind::MacroUse => Some(binding),
ImportKind::ExternCrate { .. } => None,
},
_ => None,
};
let first = ptr::eq(binding, first_binding);
let descr = get_descr(binding);
let msg = format!(
"{and_refers_to}the {item} `{name}`{which} is defined here{dots}",
and_refers_to = if first { "" } else { "...and refers to " },
item = descr,
name = name,
which = if first { "" } else { " which" },
dots = if next_binding.is_some() { "..." } else { "" },
);
let def_span = self.session.source_map().def_span(binding.span);
let mut note_span = MultiSpan::from_span(def_span);
if !first && binding.vis == ty::Visibility::Public {
note_span.push_span_label(def_span, "consider importing it directly".into());
}
err.span_note(note_span, &msg);
}
err.emit();
}

View File

@ -2188,11 +2188,8 @@ impl<'a> Resolver<'a> {
Applicability::MaybeIncorrect,
)),
)
} else if !ident.is_reserved() {
(format!("maybe a missing crate `{}`?", ident), None)
} else {
// the parser will already have complained about the keyword being used
return PathResult::NonModule(PartialRes::new(Res::Err));
(format!("maybe a missing crate `{}`?", ident), None)
}
} else if i == 0 {
(format!("use of undeclared type or module `{}`", ident), None)

View File

@ -345,6 +345,42 @@ impl<'a> base::Resolver for Resolver<'a> {
fn add_derive_copy(&mut self, expn_id: ExpnId) {
self.containers_deriving_copy.insert(expn_id);
}
// The function that implements the resolution logic of `#[cfg_accessible(path)]`.
// Returns true if the path can certainly be resolved in one of three namespaces,
// returns false if the path certainly cannot be resolved in any of the three namespaces.
// Returns `Indeterminate` if we cannot give a certain answer yet.
fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result<bool, Indeterminate> {
let span = path.span;
let path = &Segment::from_path(path);
let parent_scope = self.invocation_parent_scopes[&expn_id];
let mut indeterminate = false;
for ns in [TypeNS, ValueNS, MacroNS].iter().copied() {
match self.resolve_path(path, Some(ns), &parent_scope, false, span, CrateLint::No) {
PathResult::Module(ModuleOrUniformRoot::Module(_)) => return Ok(true),
PathResult::NonModule(partial_res) if partial_res.unresolved_segments() == 0 => {
return Ok(true);
}
PathResult::Indeterminate => indeterminate = true,
// FIXME: `resolve_path` is not ready to report partially resolved paths
// correctly, so we just report an error if the path was reported as unresolved.
// This needs to be fixed for `cfg_accessible` to be useful.
PathResult::NonModule(..) | PathResult::Failed { .. } => {}
PathResult::Module(_) => panic!("unexpected path resolution"),
}
}
if indeterminate {
return Err(Indeterminate);
}
self.session
.struct_span_err(span, "not sure whether the path is accessible or not")
.span_note(span, "`cfg_accessible` is not fully implemented")
.emit();
Ok(false)
}
}
impl<'a> Resolver<'a> {

View File

@ -182,6 +182,7 @@ symbols! {
caller_location,
cdylib,
cfg,
cfg_accessible,
cfg_attr,
cfg_attr_multi,
cfg_doctest,

View File

@ -41,10 +41,7 @@ impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
// Safe because we're !Unpin + !Drop mapping to a ?Unpin value
let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
let _guard = unsafe { set_task_context(cx) };
match gen.resume(
#[cfg(not(bootstrap))]
(),
) {
match gen.resume(()) {
GeneratorState::Yielded(()) => Poll::Pending,
GeneratorState::Complete(x) => Poll::Ready(x),
}

View File

@ -240,6 +240,7 @@
#![feature(atomic_mut_ptr)]
#![feature(box_syntax)]
#![feature(c_variadic)]
#![cfg_attr(not(bootstrap), feature(cfg_accessible))]
#![feature(cfg_target_has_atomic)]
#![feature(cfg_target_thread_local)]
#![feature(char_error_internals)]

View File

@ -53,6 +53,15 @@ pub use core::prelude::v1::{
PartialEq, PartialOrd, RustcDecodable, RustcEncodable,
};
#[cfg(not(bootstrap))]
#[unstable(
feature = "cfg_accessible",
issue = "64797",
reason = "`cfg_accessible` is not fully implemented"
)]
#[doc(hidden)]
pub use core::prelude::v1::cfg_accessible;
// The file so far is equivalent to src/libcore/prelude/v1.rs,
// and below to src/liballoc/prelude.rs.
// Those files are duplicated rather than using glob imports

View File

@ -599,24 +599,16 @@ impl Wtf8 {
#[inline]
fn final_lead_surrogate(&self) -> Option<u16> {
let len = self.len();
if len < 3 {
return None;
}
match self.bytes[(len - 3)..] {
[0xED, b2 @ 0xA0..=0xAF, b3] => Some(decode_surrogate(b2, b3)),
match self.bytes {
[.., 0xED, b2 @ 0xA0..=0xAF, b3] => Some(decode_surrogate(b2, b3)),
_ => None,
}
}
#[inline]
fn initial_trail_surrogate(&self) -> Option<u16> {
let len = self.len();
if len < 3 {
return None;
}
match self.bytes[..3] {
[0xED, b2 @ 0xB0..=0xBF, b3] => Some(decode_surrogate(b2, b3)),
match self.bytes {
[0xED, b2 @ 0xB0..=0xBF, b3, ..] => Some(decode_surrogate(b2, b3)),
_ => None,
}
}

View File

@ -12,7 +12,7 @@
# source tarball for a stable release you'll likely see `1.x.0` for rustc and
# `0.x.0` for Cargo where they were released on `date`.
date: 2020-02-29
date: 2020-03-12
rustc: beta
cargo: beta

View File

@ -1,4 +1,4 @@
// This previously triggered an ICE.
pub(in crate::r#mod) fn main() {}
//~^ ERROR expected module, found unresolved item
//~^ ERROR failed to resolve: maybe a missing crate `r#mod`

View File

@ -1,11 +1,11 @@
error[E0577]: expected module, found unresolved item `crate::r#mod`
--> $DIR/issue-61732.rs:3:8
error[E0433]: failed to resolve: maybe a missing crate `r#mod`?
--> $DIR/issue-61732.rs:3:15
|
LL | pub(in crate::r#mod) fn main() {}
| ^^^^^^^^^^^^ not a module
| ^^^^^ maybe a missing crate `r#mod`?
error: Compilation failed, aborting rustdoc
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0577`.
For more information about this error, try `rustc --explain E0433`.

View File

@ -0,0 +1,24 @@
#![feature(cfg_accessible)]
#[cfg_accessible] //~ ERROR malformed `cfg_accessible` attribute input
struct S1;
#[cfg_accessible = "value"] //~ ERROR malformed `cfg_accessible` attribute input
struct S2;
#[cfg_accessible()] //~ ERROR `cfg_accessible` path is not specified
struct S3;
#[cfg_accessible(std, core)] //~ ERROR multiple `cfg_accessible` paths are specified
struct S4;
#[cfg_accessible("std")] //~ ERROR `cfg_accessible` path cannot be a literal
struct S5;
#[cfg_accessible(std = "value")] //~ ERROR `cfg_accessible` path cannot accept arguments
struct S6;
#[cfg_accessible(std(value))] //~ ERROR `cfg_accessible` path cannot accept arguments
struct S7;
fn main() {}

View File

@ -0,0 +1,44 @@
error: malformed `cfg_accessible` attribute input
--> $DIR/cfg_accessible-input-validation.rs:3:1
|
LL | #[cfg_accessible]
| ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[cfg_accessible(path)]`
error: malformed `cfg_accessible` attribute input
--> $DIR/cfg_accessible-input-validation.rs:6:1
|
LL | #[cfg_accessible = "value"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[cfg_accessible(path)]`
error: `cfg_accessible` path is not specified
--> $DIR/cfg_accessible-input-validation.rs:9:1
|
LL | #[cfg_accessible()]
| ^^^^^^^^^^^^^^^^^^^
error: multiple `cfg_accessible` paths are specified
--> $DIR/cfg_accessible-input-validation.rs:12:23
|
LL | #[cfg_accessible(std, core)]
| ^^^^
error: `cfg_accessible` path cannot be a literal
--> $DIR/cfg_accessible-input-validation.rs:15:18
|
LL | #[cfg_accessible("std")]
| ^^^^^
error: `cfg_accessible` path cannot accept arguments
--> $DIR/cfg_accessible-input-validation.rs:18:18
|
LL | #[cfg_accessible(std = "value")]
| ^^^^^^^^^^^^^
error: `cfg_accessible` path cannot accept arguments
--> $DIR/cfg_accessible-input-validation.rs:21:18
|
LL | #[cfg_accessible(std(value))]
| ^^^^^^^^^^
error: aborting due to 7 previous errors

View File

@ -0,0 +1,9 @@
#![feature(cfg_accessible)]
#[cfg_accessible(Z)] //~ ERROR cannot determine whether the path is accessible or not
struct S;
#[cfg_accessible(S)] //~ ERROR cannot determine whether the path is accessible or not
struct Z;
fn main() {}

View File

@ -0,0 +1,14 @@
error: cannot determine whether the path is accessible or not
--> $DIR/cfg_accessible-stuck.rs:6:1
|
LL | #[cfg_accessible(S)]
| ^^^^^^^^^^^^^^^^^^^^
error: cannot determine whether the path is accessible or not
--> $DIR/cfg_accessible-stuck.rs:3:1
|
LL | #[cfg_accessible(Z)]
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View File

@ -0,0 +1,2 @@
#[cfg_accessible(std)] //~ ERROR use of unstable library feature 'cfg_accessible'
fn main() {}

View File

@ -0,0 +1,12 @@
error[E0658]: use of unstable library feature 'cfg_accessible': `cfg_accessible` is not fully implemented
--> $DIR/cfg_accessible-unstable.rs:1:3
|
LL | #[cfg_accessible(std)]
| ^^^^^^^^^^^^^^
|
= note: see issue #64797 <https://github.com/rust-lang/rust/issues/64797> for more information
= help: add `#![feature(cfg_accessible)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -0,0 +1,43 @@
#![feature(cfg_accessible)]
mod m {
pub struct ExistingPublic;
struct ExistingPrivate;
}
#[cfg_accessible(m::ExistingPublic)]
struct ExistingPublic;
// FIXME: Not implemented yet.
#[cfg_accessible(m::ExistingPrivate)] //~ ERROR not sure whether the path is accessible or not
struct ExistingPrivate;
// FIXME: Not implemented yet.
#[cfg_accessible(m::NonExistent)] //~ ERROR not sure whether the path is accessible or not
struct ExistingPrivate;
#[cfg_accessible(n::AccessibleExpanded)] // OK, `cfg_accessible` can wait and retry.
struct AccessibleExpanded;
macro_rules! generate_accessible_expanded {
() => {
mod n {
pub struct AccessibleExpanded;
}
};
}
generate_accessible_expanded!();
struct S {
field: u8,
}
// FIXME: Not implemented yet.
#[cfg_accessible(S::field)] //~ ERROR not sure whether the path is accessible or not
struct Field;
fn main() {
ExistingPublic;
AccessibleExpanded;
}

View File

@ -0,0 +1,38 @@
error: not sure whether the path is accessible or not
--> $DIR/cfg_accessible.rs:12:18
|
LL | #[cfg_accessible(m::ExistingPrivate)]
| ^^^^^^^^^^^^^^^^^^
|
note: `cfg_accessible` is not fully implemented
--> $DIR/cfg_accessible.rs:12:18
|
LL | #[cfg_accessible(m::ExistingPrivate)]
| ^^^^^^^^^^^^^^^^^^
error: not sure whether the path is accessible or not
--> $DIR/cfg_accessible.rs:16:18
|
LL | #[cfg_accessible(m::NonExistent)]
| ^^^^^^^^^^^^^^
|
note: `cfg_accessible` is not fully implemented
--> $DIR/cfg_accessible.rs:16:18
|
LL | #[cfg_accessible(m::NonExistent)]
| ^^^^^^^^^^^^^^
error: not sure whether the path is accessible or not
--> $DIR/cfg_accessible.rs:37:18
|
LL | #[cfg_accessible(S::field)]
| ^^^^^^^^
|
note: `cfg_accessible` is not fully implemented
--> $DIR/cfg_accessible.rs:37:18
|
LL | #[cfg_accessible(S::field)]
| ^^^^^^^^
error: aborting due to 3 previous errors

View File

@ -4,11 +4,26 @@ error[E0603]: struct import `ParseOptions` is private
LL | pub use parser::ParseOptions;
| ^^^^^^^^^^^^ this struct import is private
|
note: the struct import `ParseOptions` is defined here
note: the struct import `ParseOptions` is defined here...
--> $DIR/issue-55884-2.rs:9:9
|
LL | use ParseOptions;
| ^^^^^^^^^^^^
note: ...and refers to the struct import `ParseOptions` which is defined here...
--> $DIR/issue-55884-2.rs:12:9
|
LL | pub use parser::ParseOptions;
| ^^^^^^^^^^^^^^^^^^^^ consider importing it directly
note: ...and refers to the struct import `ParseOptions` which is defined here...
--> $DIR/issue-55884-2.rs:6:13
|
LL | pub use options::*;
| ^^^^^^^^^^ consider importing it directly
note: ...and refers to the struct `ParseOptions` which is defined here
--> $DIR/issue-55884-2.rs:2:5
|
LL | pub struct ParseOptions {}
| ^^^^^^^^^^^^^^^^^^^^^^^ consider importing it directly
error: aborting due to previous error

View File

@ -16,11 +16,16 @@ error[E0603]: module import `foo` is private
LL | use b::a::foo::S;
| ^^^ this module import is private
|
note: the module import `foo` is defined here
note: the module import `foo` is defined here...
--> $DIR/reexports.rs:21:17
|
LL | pub use super::foo; // This is OK since the value `foo` is visible enough.
| ^^^^^^^^^^
note: ...and refers to the module `foo` which is defined here
--> $DIR/reexports.rs:16:5
|
LL | mod foo {
| ^^^^^^^
error[E0603]: module import `foo` is private
--> $DIR/reexports.rs:34:15
@ -28,11 +33,16 @@ error[E0603]: module import `foo` is private
LL | use b::b::foo::S as T;
| ^^^ this module import is private
|
note: the module import `foo` is defined here
note: the module import `foo` is defined here...
--> $DIR/reexports.rs:26:17
|
LL | pub use super::*; // This is also OK since the value `foo` is visible enough.
| ^^^^^^^^
note: ...and refers to the module `foo` which is defined here
--> $DIR/reexports.rs:16:5
|
LL | mod foo {
| ^^^^^^^
warning: glob import doesn't reexport anything because no candidate is public enough
--> $DIR/reexports.rs:9:17

View File

@ -1,3 +1,4 @@
use extern::foo; //~ ERROR expected identifier, found keyword `extern`
//~| ERROR unresolved import `r#extern`
fn main() {}

View File

@ -9,5 +9,12 @@ help: you can escape reserved keywords to use them as identifiers
LL | use r#extern::foo;
| ^^^^^^^^
error: aborting due to previous error
error[E0432]: unresolved import `r#extern`
--> $DIR/keyword-extern-as-identifier-use.rs:1:5
|
LL | use extern::foo;
| ^^^^^^ maybe a missing crate `r#extern`?
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0432`.

View File

@ -0,0 +1,10 @@
// build-fail
// only-x86_64
fn main() {
Bug::V([0; !0]); //~ ERROR is too big for the current
}
enum Bug {
V([u8; !0]),
}

View File

@ -0,0 +1,8 @@
error: the type `[u8; 18446744073709551615]` is too big for the current architecture
--> $DIR/issue-69485-var-size-diffs-too-large.rs:5:12
|
LL | Bug::V([0; !0]);
| ^^^^^^^
error: aborting due to previous error

View File

@ -10,11 +10,16 @@ error[E0603]: function import `foo` is private
LL | use bar::glob::foo;
| ^^^ this function import is private
|
note: the function import `foo` is defined here
note: the function import `foo` is defined here...
--> $DIR/privacy2.rs:10:13
|
LL | use foo;
| ^^^
note: ...and refers to the function `foo` which is defined here
--> $DIR/privacy2.rs:14:1
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^ consider importing it directly
error: requires `sized` lang_item

View File

@ -0,0 +1,5 @@
// Regression test for issue #63882.
type A = crate::r#break; //~ ERROR cannot find type `r#break` in module `crate`
fn main() {}

View File

@ -0,0 +1,9 @@
error[E0412]: cannot find type `r#break` in module `crate`
--> $DIR/raw-ident-in-path.rs:3:17
|
LL | type A = crate::r#break;
| ^^^^^^^ not found in `crate`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0412`.

View File

@ -4,11 +4,16 @@ error[E0603]: module import `bar` is private
LL | use foo::bar::f as g;
| ^^^ this module import is private
|
note: the module import `bar` is defined here
note: the module import `bar` is defined here...
--> $DIR/shadowed-use-visibility.rs:4:9
|
LL | use foo as bar;
| ^^^^^^^^^^
note: ...and refers to the module `foo` which is defined here
--> $DIR/shadowed-use-visibility.rs:1:1
|
LL | mod foo {
| ^^^^^^^
error[E0603]: module import `f` is private
--> $DIR/shadowed-use-visibility.rs:15:10
@ -16,11 +21,16 @@ error[E0603]: module import `f` is private
LL | use bar::f::f;
| ^ this module import is private
|
note: the module import `f` is defined here
note: the module import `f` is defined here...
--> $DIR/shadowed-use-visibility.rs:11:9
|
LL | use foo as f;
| ^^^^^^^^
note: ...and refers to the module `foo` which is defined here
--> $DIR/shadowed-use-visibility.rs:1:1
|
LL | mod foo {
| ^^^^^^^
error: aborting due to 2 previous errors