diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 1f4f7d344245d..03fa5c04ec721 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -500,8 +500,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] ConstEval { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> }, [] ConstEvalRaw { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> }, [] CheckMatch(DefId), - [] SymbolName(DefId), - [] InstanceSymbolName { instance: Instance<'tcx> }, + [] SymbolName { instance: Instance<'tcx> }, [] SpecializationGraph(DefId), [] ObjectSafety(DefId), [] FulfillObligation { param_env: ParamEnv<'tcx>, trait_ref: PolyTraitRef<'tcx> }, diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 5cb5a0030f4eb..bc5caffb93464 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -941,7 +941,6 @@ impl_disk_cacheable_query!(mir_borrowck, |tcx, def_id| { impl_disk_cacheable_query!(unsafety_check_result, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(borrowck, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(check_match, |_, def_id| def_id.is_local()); -impl_disk_cacheable_query!(def_symbol_name, |_, _| true); impl_disk_cacheable_query!(predicates_of, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(used_trait_imports, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(codegen_fn_attrs, |_, _| true); diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 9c705104d1888..f64156beeaa2d 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -315,7 +315,6 @@ rustc_query_append! { [define_queries!][ <'tcx> [] fn mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx mir::Mir<'tcx>, - [] fn def_symbol_name: SymbolName(DefId) -> ty::SymbolName, [] fn symbol_name: symbol_name_dep_node(ty::Instance<'tcx>) -> ty::SymbolName, [] fn describe_def: DescribeDef(DefId) -> Option, @@ -727,7 +726,7 @@ fn mir_shim_dep_node<'tcx>(instance_def: ty::InstanceDef<'tcx>) -> DepConstructo } fn symbol_name_dep_node<'tcx>(instance: ty::Instance<'tcx>) -> DepConstructor<'tcx> { - DepConstructor::InstanceSymbolName { instance } + DepConstructor::SymbolName { instance } } fn typeck_item_bodies_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index c16f861dedb50..1b4c36b8b06c3 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -218,7 +218,6 @@ impl<'sess> OnDiskCache<'sess> { encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; - encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; encode_query_results::, _>(tcx, enc, qri)?; diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index c35cea7883f00..973291d94acdd 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1217,7 +1217,7 @@ pub fn force_from_dep_node<'tcx>( DepKind::Layout | DepKind::ConstEval | DepKind::ConstEvalRaw | - DepKind::InstanceSymbolName | + DepKind::SymbolName | DepKind::MirShim | DepKind::BorrowCheckKrate | DepKind::Specializes | @@ -1304,7 +1304,6 @@ pub fn force_from_dep_node<'tcx>( DepKind::TypeckTables => { force!(typeck_tables_of, def_id!()); } DepKind::UsedTraitImports => { force!(used_trait_imports, def_id!()); } DepKind::HasTypeckTables => { force!(has_typeck_tables, def_id!()); } - DepKind::SymbolName => { force!(def_symbol_name, def_id!()); } DepKind::SpecializationGraph => { force!(specialization_graph_of, def_id!()); } DepKind::ObjectSafety => { force!(is_object_safe, def_id!()); } DepKind::TraitImpls => { force!(trait_impls_of, def_id!()); } @@ -1486,7 +1485,6 @@ impl_load_from_cache!( BorrowCheck => borrowck, MirBorrowCheck => mir_borrowck, mir_const_qualif => mir_const_qualif, - SymbolName => def_symbol_name, ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static, CheckMatch => check_match, type_of => type_of, diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 042a8c60cfaab..e50839cd5983c 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -189,6 +189,17 @@ impl TypeMap<'ll, 'tcx> { let interner_key = self.unique_id_interner.intern(&enum_variant_type_id); UniqueTypeId(interner_key) } + + // Get the unique type id string for an enum variant part. + // Variant parts are not types and shouldn't really have their own id, + // but it makes set_members_of_composite_type() simpler. + fn get_unique_type_id_str_of_enum_variant_part<'a>(&mut self, + enum_type_id: UniqueTypeId) -> &str { + let variant_part_type_id = format!("{}_variant_part", + self.get_unique_type_id_as_string(enum_type_id)); + let interner_key = self.unique_id_interner.intern(&variant_part_type_id); + self.unique_id_interner.get(interner_key) + } } // A description of some recursive type. It can either be already finished (as @@ -1689,6 +1700,11 @@ fn prepare_enum_metadata( }, }; + let variant_part_unique_type_id_str = SmallCStr::new( + debug_context(cx).type_map + .borrow_mut() + .get_unique_type_id_str_of_enum_variant_part(unique_type_id) + ); let empty_array = create_DIArray(DIB(cx), &[]); let variant_part = unsafe { llvm::LLVMRustDIBuilderCreateVariantPart( @@ -1702,7 +1718,7 @@ fn prepare_enum_metadata( DIFlags::FlagZero, discriminator_metadata, empty_array, - unique_type_id_str.as_ptr()) + variant_part_unique_type_id_str.as_ptr()) }; // The variant part must be wrapped in a struct according to DWARF. diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index ebd48f0ae1e2b..d50a9a1607b24 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -101,7 +101,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_mir::monomorphize::item::{InstantiationMode, MonoItem, MonoItemExt}; use rustc_mir::monomorphize::Instance; -use syntax_pos::symbol::Symbol; +use syntax_pos::symbol::{Symbol, InternedString}; use log::debug; @@ -110,7 +110,6 @@ use std::mem::{self, discriminant}; pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { - def_symbol_name, symbol_name, ..*providers @@ -222,21 +221,13 @@ fn get_symbol_hash<'a, 'tcx>( hasher.finish() } -fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - SymbolPrinter { - tcx, - path: SymbolPath::new(), - keep_within_component: false, - }.print_def_path(def_id, &[]).unwrap().path.into_interned() -} - -fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { +fn symbol_name(tcx: TyCtxt<'_, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { ty::SymbolName { - name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_interned_str(), + name: compute_symbol_name(tcx, instance), } } -fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> String { +fn compute_symbol_name(tcx: TyCtxt<'_, 'tcx, 'tcx>, instance: Instance<'tcx>) -> InternedString { let def_id = instance.def_id(); let substs = instance.substs; @@ -247,11 +238,13 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance if def_id.is_local() { if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return tcx.sess.generate_plugin_registrar_symbol(disambiguator); + return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator)) + .as_interned_str(); } if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return tcx.sess.generate_proc_macro_decls_symbol(disambiguator); + return Symbol::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator)) + .as_interned_str(); } } @@ -268,20 +261,20 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let attrs = tcx.codegen_fn_attrs(def_id); if is_foreign { if let Some(name) = attrs.link_name { - return name.to_string(); + return name.as_interned_str(); } // Don't mangle foreign items. - return tcx.item_name(def_id).to_string(); + return tcx.item_name(def_id); } if let Some(name) = &attrs.export_name { // Use provided name - return name.to_string(); + return name.as_interned_str(); } if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { // Don't mangle - return tcx.item_name(def_id).to_string(); + return tcx.item_name(def_id); } // We want to compute the "type" of this item. Unfortunately, some @@ -321,15 +314,15 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let mut printer = SymbolPrinter { tcx, - path: SymbolPath::from_interned(tcx.def_symbol_name(def_id)), + path: SymbolPath::new(), keep_within_component: false, - }; + }.print_def_path(def_id, &[]).unwrap(); if instance.is_vtable_shim() { let _ = printer.write_str("{{vtable-shim}}"); } - printer.path.finish(hash) + Symbol::intern(&printer.path.finish(hash)).as_interned_str() } // Follow C++ namespace-mangling style, see @@ -361,22 +354,6 @@ impl SymbolPath { result } - fn from_interned(symbol: ty::SymbolName) -> Self { - let mut result = SymbolPath { - result: String::with_capacity(64), - temp_buf: String::with_capacity(16), - }; - result.result.push_str(&symbol.as_str()); - result - } - - fn into_interned(mut self) -> ty::SymbolName { - self.finalize_pending_component(); - ty::SymbolName { - name: Symbol::intern(&self.result).as_interned_str(), - } - } - fn finalize_pending_component(&mut self) { if !self.temp_buf.is_empty() { let _ = write!(self.result, "{}{}", self.temp_buf.len(), self.temp_buf); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 492ac1bf14dcc..1fae931e9f1fd 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1619,6 +1619,8 @@ impl LintPass for KeywordIdents { } } +struct UnderMacro(bool); + impl KeywordIdents { fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: TokenStream) { for tt in tokens.into_trees() { @@ -1626,7 +1628,7 @@ impl KeywordIdents { TokenTree::Token(span, tok) => match tok.ident() { // only report non-raw idents Some((ident, false)) => { - self.check_ident(cx, ast::Ident { + self.check_ident_token(cx, UnderMacro(true), ast::Ident { span: span.substitute_dummy(ident.span), ..ident }); @@ -1639,16 +1641,12 @@ impl KeywordIdents { } } } -} -impl EarlyLintPass for KeywordIdents { - fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef, _id: ast::NodeId) { - self.check_tokens(cx, mac_def.stream()); - } - fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::Mac) { - self.check_tokens(cx, mac.node.tts.clone().into()); - } - fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) { + fn check_ident_token(&mut self, + cx: &EarlyContext<'_>, + UnderMacro(under_macro): UnderMacro, + ident: ast::Ident) + { let ident_str = &ident.as_str()[..]; let cur_edition = cx.sess.edition(); let is_raw_ident = |ident: ast::Ident| { @@ -1657,7 +1655,22 @@ impl EarlyLintPass for KeywordIdents { let next_edition = match cur_edition { Edition::Edition2015 => { match ident_str { - "async" | "try" | "dyn" => Edition::Edition2018, + "async" | "try" => Edition::Edition2018, + + // rust-lang/rust#56327: Conservatively do not + // attempt to report occurrences of `dyn` within + // macro definitions or invocations, because `dyn` + // can legitimately occur as a contextual keyword + // in 2015 code denoting its 2018 meaning, and we + // do not want rustfix to inject bugs into working + // code by rewriting such occurrences. + // + // But if we see `dyn` outside of a macro, we know + // its precise role in the parsed AST and thus are + // assured this is truly an attempt to use it as + // an identifier. + "dyn" if !under_macro => Edition::Edition2018, + // Only issue warnings for `await` if the `async_await` // feature isn't being used. Otherwise, users need // to keep using `await` for the macro exposed by std. @@ -1715,6 +1728,18 @@ impl EarlyLintPass for KeywordIdents { } } +impl EarlyLintPass for KeywordIdents { + fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef, _id: ast::NodeId) { + self.check_tokens(cx, mac_def.stream()); + } + fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::Mac) { + self.check_tokens(cx, mac.node.tts.clone().into()); + } + fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) { + self.check_ident_token(cx, UnderMacro(false), ident); + } +} + pub struct ExplicitOutlivesRequirements; diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs index ad108587247fb..54fc63f30571e 100644 --- a/src/librustc_mir/transform/lower_128bit.rs +++ b/src/librustc_mir/transform/lower_128bit.rs @@ -138,7 +138,7 @@ fn check_lang_item_type<'a, 'tcx, D>( let place_ty = place.ty(local_decls, tcx).to_ty(tcx); let expected = [lhs_ty, rhs_ty, place_ty]; assert_eq!(sig.inputs_and_output[..], expected, - "lang item {}", tcx.def_symbol_name(did)); + "lang item `{}`", tcx.def_path_str(did)); did } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a403f0845ceef..27ffe4583df25 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1769,9 +1769,13 @@ fn get_real_types( generics: &Generics, arg: &Type, cx: &DocContext<'_>, + recurse: i32, ) -> FxHashSet { let arg_s = arg.to_string(); let mut res = FxHashSet::default(); + if recurse >= 10 { // FIXME: remove this whole recurse thing when the recursion bug is fixed + return res; + } if arg.is_full_generic() { if let Some(where_pred) = generics.where_predicates.iter().find(|g| { match g { @@ -1788,7 +1792,7 @@ fn get_real_types( continue } if let Some(ty) = x.get_type(cx) { - let adds = get_real_types(generics, &ty, cx); + let adds = get_real_types(generics, &ty, cx, recurse + 1); if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { @@ -1806,7 +1810,7 @@ fn get_real_types( }) { for bound in bound.get_bounds().unwrap_or_else(|| &[]) { if let Some(ty) = bound.get_trait_type() { - let adds = get_real_types(generics, &ty, cx); + let adds = get_real_types(generics, &ty, cx, recurse + 1); if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { @@ -1820,7 +1824,7 @@ fn get_real_types( if let Some(gens) = arg.generics() { for gen in gens.iter() { if gen.is_full_generic() { - let adds = get_real_types(generics, gen, cx); + let adds = get_real_types(generics, gen, cx, recurse + 1); if !adds.is_empty() { res.extend(adds); } @@ -1847,7 +1851,7 @@ pub fn get_all_types( if arg.type_.is_self_type() { continue; } - let args = get_real_types(generics, &arg.type_, cx); + let args = get_real_types(generics, &arg.type_, cx, 0); if !args.is_empty() { all_types.extend(args); } else { @@ -1857,7 +1861,7 @@ pub fn get_all_types( let ret_types = match decl.output { FunctionRetTy::Return(ref return_type) => { - let mut ret = get_real_types(generics, &return_type, cx); + let mut ret = get_real_types(generics, &return_type, cx, 0); if ret.is_empty() { ret.insert(return_type.clone()); } diff --git a/src/test/debuginfo/enum-thinlto.rs b/src/test/debuginfo/enum-thinlto.rs new file mode 100644 index 0000000000000..7f15ed90e67b3 --- /dev/null +++ b/src/test/debuginfo/enum-thinlto.rs @@ -0,0 +1,48 @@ +// ignore-tidy-linelength + +// Require LLVM with DW_TAG_variant_part and a gdb that can read it. +// min-system-llvm-version: 8.0 +// min-gdb-version: 8.2 + +// compile-flags:-g -Z thinlto + +// === GDB TESTS =================================================================================== + +// gdb-command:run + +// gdb-command:print *abc +// gdbr-check:$1 = enum_thinlto::ABC::TheA{x: 0, y: 8970181431921507452} + +// === LLDB TESTS ================================================================================== + +// lldb-command:run + +// lldb-command:print *abc +// lldbg-check:(enum_thinlto::ABC) $0 = ABC { } + +#![allow(unused_variables)] +#![feature(omit_gdb_pretty_printer_section)] +#![omit_gdb_pretty_printer_section] + +// The first element is to ensure proper alignment, irrespective of the machines word size. Since +// the size of the discriminant value is machine dependent, this has be taken into account when +// datatype layout should be predictable as in this case. +#[derive(Debug)] +enum ABC { + TheA { x: i64, y: i64 }, + TheB (i64, i32, i32), +} + +fn main() { + let abc = ABC::TheA { x: 0, y: 0x7c7c_7c7c_7c7c_7c7c }; + + f(&abc); +} + +fn f(abc: &ABC) { + zzz(); // #break + + println!("{:?}", abc); +} + +fn zzz() {()} diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed new file mode 100644 index 0000000000000..003736208ed38 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.fixed @@ -0,0 +1,81 @@ +// Under the 2015 edition with the keyword_idents lint, `dyn` is not +// entirely acceptable as an identifier. We currently do not attempt +// to detect or fix uses of `dyn` under a macro. Since we are testing +// this file via `rustfix`, we want the rustfix output to be +// compilable; so the macros here carefully use `dyn` "correctly." + +// run-rustfix + +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod r#dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + pub struct r#dyn; +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + } +} +use outer_mod::r#dyn::r#dyn; +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + +fn main() { + match r#dyn { r#dyn => {} } +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + macro_defn::r#dyn(); +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + + macro_defn::boxed(); +} + +mod macro_defn { + use super::Trait; + + macro_rules! r#dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + + // Note that we do not lint nor fix occurrences under macros + ($dyn:tt) => { (Box, Box<$dyn Trait>) } + } + + pub fn r#dyn() -> ::outer_mod::r#dyn::r#dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + ::outer_mod::r#dyn::r#dyn +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + } + + + + pub fn boxed() -> r#dyn!( + //~^ ERROR `dyn` is a keyword + //~| WARN was previously accepted + + // Note that we do not lint nor fix occurrences under macros + dyn + ) + { + (Box::new(1), Box::new(2)) + } +} + +pub trait Trait { } + +impl Trait for u32 { } diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs new file mode 100644 index 0000000000000..0e5c39fc501be --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs @@ -0,0 +1,81 @@ +// Under the 2015 edition with the keyword_idents lint, `dyn` is not +// entirely acceptable as an identifier. We currently do not attempt +// to detect or fix uses of `dyn` under a macro. Since we are testing +// this file via `rustfix`, we want the rustfix output to be +// compilable; so the macros here carefully use `dyn` "correctly." + +// run-rustfix + +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + pub struct dyn; +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + } +} +use outer_mod::dyn::dyn; +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + +fn main() { + match dyn { dyn => {} } +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + macro_defn::dyn(); +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + + macro_defn::boxed(); +} + +mod macro_defn { + use super::Trait; + + macro_rules! dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted + + // Note that we do not lint nor fix occurrences under macros + ($dyn:tt) => { (Box, Box<$dyn Trait>) } + } + + pub fn dyn() -> ::outer_mod::dyn::dyn { +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + ::outer_mod::dyn::dyn +//~^ ERROR `dyn` is a keyword +//~| WARN was previously accepted +//~| ERROR `dyn` is a keyword +//~| WARN was previously accepted + } + + + + pub fn boxed() -> dyn!( + //~^ ERROR `dyn` is a keyword + //~| WARN was previously accepted + + // Note that we do not lint nor fix occurrences under macros + dyn + ) + { + (Box::new(1), Box::new(2)) + } +} + +pub trait Trait { } + +impl Trait for u32 { } diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr new file mode 100644 index 0000000000000..361727733bc57 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr @@ -0,0 +1,133 @@ +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:13:13 + | +LL | pub mod dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | +note: lint level defined here + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:10:9 + | +LL | #![deny(keyword_idents)] + | ^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:16:20 + | +LL | pub struct dyn; + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:21:16 + | +LL | use outer_mod::dyn::dyn; + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:21:21 + | +LL | use outer_mod::dyn::dyn; + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:28:11 + | +LL | match dyn { dyn => {} } + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:28:17 + | +LL | match dyn { dyn => {} } + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:33:17 + | +LL | macro_defn::dyn(); + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:43:18 + | +LL | macro_rules! dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:51:12 + | +LL | pub fn dyn() -> ::outer_mod::dyn::dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:51:34 + | +LL | pub fn dyn() -> ::outer_mod::dyn::dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:51:39 + | +LL | pub fn dyn() -> ::outer_mod::dyn::dyn { + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:58:22 + | +LL | ::outer_mod::dyn::dyn + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:58:27 + | +LL | ::outer_mod::dyn::dyn + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: `dyn` is a keyword in the 2018 edition + --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:67:23 + | +LL | pub fn boxed() -> dyn!( + | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! + = note: for more information, see issue #49716 + +error: aborting due to 14 previous errors + diff --git a/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs b/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs new file mode 100644 index 0000000000000..f535791d7fbe4 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs @@ -0,0 +1,51 @@ +// compile-pass + +// Under the 2015 edition with the keyword_idents lint, `dyn` is +// not entirely acceptable as an identifier. +// +// We currently do not attempt to detect or fix uses of `dyn` as an +// identifier under a macro, including under the declarative `macro` +// forms from macros 1.2 and macros 2.0. + +#![feature(decl_macro)] +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod r#dyn { + pub struct r#dyn; + } +} + +// Here we are illustrating that the current lint does not flag the +// occurrences of `dyn` in this macro definition; however, it +// certainly *could* (and it would be nice if it did), since these +// occurrences are not compatible with the 2018 edition's +// interpretation of `dyn` as a keyword. +macro defn_has_dyn_idents() { ::outer_mod::dyn::dyn } + +struct X; +trait Trait { fn hello(&self) { }} +impl Trait for X { } + +macro tt_trait($arg:tt) { & $arg Trait } +macro id_trait($id:ident) { & $id Trait } + +fn main() { + defn_has_dyn_idents!(); + + // Here we are illustrating that the current lint does not flag + // the occurrences of `dyn` in these macro invocations. It + // definitely should *not* flag the one in `tt_trait`, since that + // is expanding in a valid fashion to `&dyn Trait`. + // + // It is arguable whether it would be valid to flag the occurrence + // in `id_trait`, since that macro specifies that it takes an + // `ident` as its input. + fn f_tt(x: &X) -> tt_trait!(dyn) { x } + fn f_id(x: &X) -> id_trait!(dyn) { x } + + let x = X; + f_tt(&x).hello(); + f_id(&x).hello(); +} diff --git a/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs new file mode 100644 index 0000000000000..27e490558689f --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs @@ -0,0 +1,56 @@ +// compile-pass + +// Under the 2015 edition with the keyword_idents lint, `dyn` is +// not entirely acceptable as an identifier. +// +// We currently do not attempt to detect or fix uses of `dyn` as an +// identifier under a macro. + +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod r#dyn { + pub struct r#dyn; + } +} + +// Here we are illustrating that the current lint does not flag the +// occurrences of `dyn` in this macro definition; however, it +// certainly *could* (and it would be nice if it did), since these +// occurrences are not compatible with the 2018 edition's +// interpretation of `dyn` as a keyword. +macro_rules! defn_has_dyn_idents { + () => { ::outer_mod::dyn::dyn } +} + +struct X; +trait Trait { fn hello(&self) { }} +impl Trait for X { } + +macro_rules! tt_trait { + ($arg:tt) => { & $arg Trait } +} + +macro_rules! id_trait { + ($id:ident) => { & $id Trait } +} + +fn main() { + defn_has_dyn_idents!(); + + // Here we are illustrating that the current lint does not flag + // the occurrences of `dyn` in these macro invocations. It + // definitely should *not* flag the one in `tt_trait`, since that + // is expanding in a valid fashion to `&dyn Trait`. + // + // It is arguable whether it would be valid to flag the occurrence + // in `id_trait`, since that macro specifies that it takes an + // `ident` as its input. + fn f_tt(x: &X) -> tt_trait!(dyn) { x } + fn f_id(x: &X) -> id_trait!(dyn) { x } + + let x = X; + f_tt(&x).hello(); + f_id(&x).hello(); +} diff --git a/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs b/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs new file mode 100644 index 0000000000000..8cef5c2b34947 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs @@ -0,0 +1,27 @@ +// Under the 2015 edition without the keyword_idents lint, `dyn` is +// entirely acceptable as an identifier. + +// compile-pass + +#![allow(non_camel_case_types)] + +mod outer_mod { + pub mod dyn { + pub struct dyn; + } +} +use outer_mod::dyn::dyn; + +fn main() { + match dyn { dyn => {} } + macro_defn::dyn(); +} +mod macro_defn { + macro_rules! dyn { + () => { ::outer_mod::dyn::dyn } + } + + pub fn dyn() -> ::outer_mod::dyn::dyn { + dyn!() + } +} diff --git a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs new file mode 100644 index 0000000000000..ff3830d61755a --- /dev/null +++ b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs @@ -0,0 +1,25 @@ +// compile-pass + +// rust-lang/rust#56327: Some occurrences of `dyn` within a macro are +// not instances of identifiers, and thus should *not* be caught by the +// keyword_ident lint. +// +// Otherwise, rustfix replaces the type `Box` with +// `Box`, which is injecting a bug rather than fixing +// anything. + +#![deny(rust_2018_compatibility)] + +macro_rules! foo { + () => { + fn generated_foo() { + let _x: Box; + } + } +} + +foo!(); + +fn main() { + generated_foo(); +} diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index e61714f583c7a..0611e53d0927c 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -523,12 +523,18 @@ impl Builder { pkgname: &str, dst: &mut BTreeMap, targets: &[&str]) { - let (version, is_present) = self.cached_version(pkgname) + let (version, mut is_present) = self.cached_version(pkgname) .as_ref() .cloned() .map(|version| (version, true)) .unwrap_or_default(); + // miri needs to build std with xargo, which doesn't allow stable/beta: + // + if pkgname == "miri-preview" && self.rust_release != "nightly" { + is_present = false; // ignore it + } + let targets = targets.iter().map(|name| { if is_present { let filename = self.filename(pkgname, name);