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:
commit
5e9ebf4da3
@ -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;
|
||||
|
||||
|
@ -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>,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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")]
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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(),
|
||||
},
|
||||
|
||||
|
54
src/librustc_builtin_macros/cfg_accessible.rs
Normal file
54
src/librustc_builtin_macros/cfg_accessible.rs
Normal 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()),
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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)]
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)]`.
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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> {
|
||||
|
@ -182,6 +182,7 @@ symbols! {
|
||||
caller_location,
|
||||
cdylib,
|
||||
cfg,
|
||||
cfg_accessible,
|
||||
cfg_attr,
|
||||
cfg_attr_multi,
|
||||
cfg_doctest,
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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`
|
||||
|
@ -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`.
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
@ -0,0 +1,2 @@
|
||||
#[cfg_accessible(std)] //~ ERROR use of unstable library feature 'cfg_accessible'
|
||||
fn main() {}
|
@ -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`.
|
43
src/test/ui/conditional-compilation/cfg_accessible.rs
Normal file
43
src/test/ui/conditional-compilation/cfg_accessible.rs
Normal 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;
|
||||
}
|
38
src/test/ui/conditional-compilation/cfg_accessible.stderr
Normal file
38
src/test/ui/conditional-compilation/cfg_accessible.stderr
Normal 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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,3 +1,4 @@
|
||||
use extern::foo; //~ ERROR expected identifier, found keyword `extern`
|
||||
//~| ERROR unresolved import `r#extern`
|
||||
|
||||
fn main() {}
|
||||
|
@ -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`.
|
||||
|
10
src/test/ui/lint/issue-69485-var-size-diffs-too-large.rs
Normal file
10
src/test/ui/lint/issue-69485-var-size-diffs-too-large.rs
Normal 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]),
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
5
src/test/ui/resolve/raw-ident-in-path.rs
Normal file
5
src/test/ui/resolve/raw-ident-in-path.rs
Normal 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() {}
|
9
src/test/ui/resolve/raw-ident-in-path.stderr
Normal file
9
src/test/ui/resolve/raw-ident-in-path.stderr
Normal 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`.
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user