diff --git a/RELEASES.md b/RELEASES.md index 10e485c1a40d5..427aa71b4b5dc 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,13 @@ +Version 1.41.1 (2020-02-27) +=========================== + +* [Always check types of static items][69145] +* [Always check lifetime bounds of `Copy` impls][69145] +* [Fix miscompilation in callers of `Layout::repeat`][69225] + +[69225]: https://github.com/rust-lang/rust/issues/69225 +[69145]: https://github.com/rust-lang/rust/pull/69145 + Version 1.41.0 (2020-01-30) =========================== diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index bca96b77812c8..7bd1d00e84ca1 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -267,6 +267,9 @@ mod bool; mod tuple; mod unit; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub mod primitive; + // Pull in the `core_arch` crate directly into libcore. The contents of // `core_arch` are in a different repository: rust-lang/stdarch. // diff --git a/src/libcore/primitive.rs b/src/libcore/primitive.rs new file mode 100644 index 0000000000000..e20b2c5c9382a --- /dev/null +++ b/src/libcore/primitive.rs @@ -0,0 +1,67 @@ +//! This module reexports the primitive types to allow usage that is not +//! possibly shadowed by other declared types. +//! +//! This is normally only useful in macro generated code. +//! +//! An example of this is when generating a new struct and an impl for it: +//! +//! ```rust,compile_fail +//! pub struct bool; +//! +//! impl QueryId for bool { +//! const SOME_PROPERTY: bool = true; +//! } +//! +//! # trait QueryId { const SOME_PROPERTY: core::primitive::bool; } +//! ``` +//! +//! Note that the `SOME_PROPERTY` associated constant would not compile, as its +//! type `bool` refers to the struct, rather than to the primitive bool type. +//! +//! A correct implementation could look like: +//! +//! ```rust +//! # #[allow(non_camel_case_types)] +//! pub struct bool; +//! +//! impl QueryId for bool { +//! const SOME_PROPERTY: core::primitive::bool = true; +//! } +//! +//! # trait QueryId { const SOME_PROPERTY: core::primitive::bool; } +//! ``` + +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use bool; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use char; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use f32; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use f64; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use i128; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use i16; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use i32; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use i64; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use i8; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use isize; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use str; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use u128; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use u16; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use u32; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use u64; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use u8; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use usize; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index e59738d888608..c027d6f61b01f 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1526,7 +1526,7 @@ impl<'tcx> GlobalCtxt<'tcx> { ty::tls::with_related_context(tcx, |icx| { let new_icx = ty::tls::ImplicitCtxt { tcx, - query: icx.query.clone(), + query: icx.query, diagnostics: icx.diagnostics, layout_depth: icx.layout_depth, task_deps: icx.task_deps, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a195c944ff28d..d17ef3a6c9a8c 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1447,7 +1447,7 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd> { impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&TraitRef<'tcx>> { fn to_predicate(&self) -> Predicate<'tcx> { ty::Predicate::Trait( - ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }), + ty::Binder::dummy(ty::TraitPredicate { trait_ref: *self.value }), self.constness, ) } diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index 8aae57e72cd52..3394fed840222 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -173,7 +173,7 @@ impl<'tcx> QueryLatch<'tcx> { return CycleError { usage, cycle }; } - current_job = info.job.parent.clone(); + current_job = info.job.parent; } panic!("did not find a cycle") diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 2b223d92ff198..3431c1b8e9d42 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -3,7 +3,7 @@ use crate::pp::{self, Breaks}; use rustc_span::edition::Edition; use rustc_span::source_map::{SourceMap, Spanned}; -use rustc_span::symbol::{kw, sym}; +use rustc_span::symbol::{kw, sym, IdentPrinter}; use rustc_span::{BytePos, FileName, Span}; use syntax::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; use syntax::ast::{Attribute, GenericArg, MacArgs}; @@ -196,40 +196,6 @@ pub fn literal_to_string(lit: token::Lit) -> String { out } -/// Print an ident from AST, `$crate` is converted into its respective crate name. -pub fn ast_ident_to_string(ident: ast::Ident, is_raw: bool) -> String { - ident_to_string(ident.name, is_raw, Some(ident.span)) -} - -// AST pretty-printer is used as a fallback for turning AST structures into token streams for -// proc macros. Additionally, proc macros may stringify their input and expect it survive the -// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30). -// So we need to somehow pretty-print `$crate` in a way preserving at least some of its -// hygiene data, most importantly name of the crate it refers to. -// As a result we print `$crate` as `crate` if it refers to the local crate -// and as `::other_crate_name` if it refers to some other crate. -// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing, -// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents, -// so we should not perform this lossy conversion if the top level call to the pretty-printer was -// done for a token stream or a single token. -fn ident_to_string(name: ast::Name, is_raw: bool, convert_dollar_crate: Option) -> String { - if is_raw { - format!("r#{}", name) - } else { - if name == kw::DollarCrate { - if let Some(span) = convert_dollar_crate { - let converted = span.ctxt().dollar_crate_name(); - return if converted.is_path_segment_keyword() { - converted.to_string() - } else { - format!("::{}", converted) - }; - } - } - name.to_string() - } -} - /// Print the token kind precisely, without converting `$crate` into its respective crate name. pub fn token_kind_to_string(tok: &TokenKind) -> String { token_kind_to_string_ext(tok, None) @@ -280,7 +246,7 @@ fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option) token::Literal(lit) => literal_to_string(lit), /* Name components */ - token::Ident(s, is_raw) => ident_to_string(s, is_raw, convert_dollar_crate), + token::Ident(s, is_raw) => IdentPrinter::new(s, is_raw, convert_dollar_crate).to_string(), token::Lifetime(s) => s.to_string(), /* Other */ @@ -315,14 +281,11 @@ pub fn nonterminal_to_string(nt: &Nonterminal) -> String { token::NtBlock(ref e) => block_to_string(e), token::NtStmt(ref e) => stmt_to_string(e), token::NtPat(ref e) => pat_to_string(e), - token::NtIdent(e, is_raw) => ast_ident_to_string(e, is_raw), + token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(), token::NtLifetime(e) => e.to_string(), token::NtLiteral(ref e) => expr_to_string(e), token::NtTT(ref tree) => tt_to_string(tree.clone()), - // FIXME(Centril): merge these variants. - token::NtImplItem(ref e) | token::NtTraitItem(ref e) => assoc_item_to_string(e), token::NtVis(ref e) => vis_to_string(e), - token::NtForeignItem(ref e) => foreign_item_to_string(e), } } @@ -358,10 +321,6 @@ pub fn item_to_string(i: &ast::Item) -> String { to_string(|s| s.print_item(i)) } -fn assoc_item_to_string(i: &ast::AssocItem) -> String { - to_string(|s| s.print_assoc_item(i)) -} - pub fn generic_params_to_string(generic_params: &[ast::GenericParam]) -> String { to_string(|s| s.print_generic_params(generic_params)) } @@ -404,10 +363,6 @@ pub fn param_to_string(arg: &ast::Param) -> String { to_string(|s| s.print_param(arg, false)) } -fn foreign_item_to_string(arg: &ast::ForeignItem) -> String { - to_string(|s| s.print_foreign_item(arg)) -} - fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String { format!("{}{}", to_string(|s| s.print_visibility(vis)), s) } @@ -819,7 +774,7 @@ impl<'a> PrintState<'a> for State<'a> { } fn print_ident(&mut self, ident: ast::Ident) { - self.s.word(ast_ident_to_string(ident, ident.is_raw_guess())); + self.s.word(IdentPrinter::for_ast_ident(ident, ident.is_raw_guess()).to_string()); self.ann.post(self, AnnNode::Ident(&ident)) } diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 9ceb75a603bc4..4248627dccaf2 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -31,7 +31,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => { let val = self.eval_mir_constant(constant)?; let ty = self.monomorphize(&constant.literal.ty); - Ok(OperandRef::from_const(bx, val.clone(), ty)) + Ok(OperandRef::from_const(bx, val, ty)) } } } diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 334daddba8820..6711a49b2b7c1 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -314,7 +314,7 @@ impl ObligationForest { return Ok(()); } - match self.active_cache.entry(obligation.as_cache_key().clone()) { + match self.active_cache.entry(obligation.as_cache_key()) { Entry::Occupied(o) => { let node = &mut self.nodes[*o.get()]; if let Some(parent_index) = parent { @@ -385,7 +385,7 @@ impl ObligationForest { self.error_cache .entry(node.obligation_tree_id) .or_default() - .insert(node.obligation.as_cache_key().clone()); + .insert(node.obligation.as_cache_key()); } /// Performs a pass through the obligation list. This must diff --git a/src/librustc_error_codes/error_codes/E0370.md b/src/librustc_error_codes/error_codes/E0370.md index a3d280fc6dccc..14e954722a250 100644 --- a/src/librustc_error_codes/error_codes/E0370.md +++ b/src/librustc_error_codes/error_codes/E0370.md @@ -1,5 +1,7 @@ The maximum value of an enum was reached, so it cannot be automatically -set in the next enum value. Erroneous code example: +set in the next enum value. + +Erroneous code example: ```compile_fail,E0370 #[repr(i64)] diff --git a/src/librustc_error_codes/error_codes/E0371.md b/src/librustc_error_codes/error_codes/E0371.md index 9363cddb1dd47..a44721346e20d 100644 --- a/src/librustc_error_codes/error_codes/E0371.md +++ b/src/librustc_error_codes/error_codes/E0371.md @@ -1,9 +1,6 @@ -When `Trait2` is a subtrait of `Trait1` (for example, when `Trait2` has a -definition like `trait Trait2: Trait1 { ... }`), it is not allowed to implement -`Trait1` for `Trait2`. This is because `Trait2` already implements `Trait1` by -definition, so it is not useful to do this. +A trait was implemented on another which already automatically implemented it. -Example: +Erroneous code examples: ```compile_fail,E0371 trait Foo { fn foo(&self) { } } @@ -15,3 +12,8 @@ impl Foo for Baz { } // error, `Baz` implements `Bar` which implements `Foo` impl Baz for Baz { } // error, `Baz` (trivially) implements `Baz` impl Baz for Bar { } // Note: This is OK ``` + +When `Trait2` is a subtrait of `Trait1` (for example, when `Trait2` has a +definition like `trait Trait2: Trait1 { ... }`), it is not allowed to implement +`Trait1` for `Trait2`. This is because `Trait2` already implements `Trait1` by +definition, so it is not useful to do this. diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index bbea066b048d2..8ed7bbf6e1276 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -669,12 +669,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> { SyntaxExtensionKind::Attr(expander) => { self.gate_proc_macro_input(&item); self.gate_proc_macro_attr_item(span, &item); + // `Annotatable` can be converted into tokens directly, but we are packing it + // into a nonterminal as a piece of AST to make the produced token stream + // look nicer in pretty-printed form. This may be no longer necessary. let item_tok = TokenTree::token( token::Interpolated(Lrc::new(match item { Annotatable::Item(item) => token::NtItem(item), - Annotatable::TraitItem(item) => token::NtTraitItem(item), - Annotatable::ImplItem(item) => token::NtImplItem(item), - Annotatable::ForeignItem(item) => token::NtForeignItem(item), + Annotatable::TraitItem(item) + | Annotatable::ImplItem(item) + | Annotatable::ForeignItem(item) => { + token::NtItem(P(item.and_then(ast::AssocItem::into_item))) + } Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()), Annotatable::Expr(expr) => token::NtExpr(expr), Annotatable::Arm(..) diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs index e2e061c185c03..91658db1a7a3d 100644 --- a/src/librustc_feature/builtin_attrs.rs +++ b/src/librustc_feature/builtin_attrs.rs @@ -234,7 +234,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ungated!(export_name, Whitelisted, template!(NameValueStr: "name")), ungated!(link_section, Whitelisted, template!(NameValueStr: "name")), ungated!(no_mangle, Whitelisted, template!(Word)), - ungated!(used, Whitelisted, template!(Word)), + ungated!(used, Normal, template!(Word)), // Limits: ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N")), @@ -250,17 +250,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ungated!(path, Normal, template!(NameValueStr: "file")), ungated!(no_std, CrateLevel, template!(Word)), ungated!(no_implicit_prelude, Normal, template!(Word)), - ungated!(non_exhaustive, Whitelisted, template!(Word)), + ungated!(non_exhaustive, Normal, template!(Word)), // Runtime ungated!(windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console")), ungated!(panic_handler, Normal, template!(Word)), // RFC 2070 // Code generation: - ungated!(inline, Whitelisted, template!(Word, List: "always|never")), + ungated!(inline, Normal, template!(Word, List: "always|never")), ungated!(cold, Whitelisted, template!(Word)), ungated!(no_builtins, Whitelisted, template!(Word)), - ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)), + ungated!(target_feature, Normal, template!(List: r#"enable = "name""#)), gated!( no_sanitize, Whitelisted, template!(List: "address, memory, thread"), @@ -275,7 +275,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // ========================================================================== // Linking: - gated!(naked, Whitelisted, template!(Word), naked_functions, experimental!(naked)), + gated!(naked, Normal, template!(Word), naked_functions, experimental!(naked)), gated!( link_args, Normal, template!(NameValueStr: "args"), "the `link_args` attribute is experimental and not portable across platforms, \ @@ -332,7 +332,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)), - gated!(track_caller, Whitelisted, template!(Word), experimental!(track_caller)), + gated!(track_caller, Normal, template!(Word), experimental!(track_caller)), gated!( register_attr, CrateLevel, template!(List: "attr1, attr2, ..."), experimental!(register_attr), diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index c9faa299d372e..3fde04c294ef2 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -1,8 +1,8 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; -use rustc_ast_pretty::pprust::{self, Comments, PrintState}; +use rustc_ast_pretty::pprust::{Comments, PrintState}; use rustc_span::source_map::{SourceMap, Spanned}; -use rustc_span::symbol::kw; +use rustc_span::symbol::{kw, IdentPrinter}; use rustc_span::{self, BytePos, FileName}; use rustc_target::spec::abi::Abi; use syntax::ast; @@ -126,7 +126,7 @@ impl<'a> PrintState<'a> for State<'a> { } fn print_ident(&mut self, ident: ast::Ident) { - self.s.word(pprust::ast_ident_to_string(ident, ident.is_raw_guess())); + self.s.word(IdentPrinter::for_ast_ident(ident, ident.is_raw_guess()).to_string()); self.ann.post(self, AnnNode::Name(&ident.name)) } diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/src/librustc_infer/infer/lexical_region_resolve/mod.rs index 0b5536219e566..fc9f3bb076745 100644 --- a/src/librustc_infer/infer/lexical_region_resolve/mod.rs +++ b/src/librustc_infer/infer/lexical_region_resolve/mod.rs @@ -848,7 +848,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { for upper_bound in &upper_bounds { if let ty::RePlaceholder(p) = upper_bound.region { if node_universe.cannot_name(p.universe) { - let origin = self.var_infos[node_idx].origin.clone(); + let origin = self.var_infos[node_idx].origin; errors.push(RegionResolutionError::UpperBoundUniverseConflict( node_idx, origin, diff --git a/src/librustc_macros/src/hash_stable.rs b/src/librustc_macros/src/hash_stable.rs index e6f457dd663c2..dc6ae961e5a6e 100644 --- a/src/librustc_macros/src/hash_stable.rs +++ b/src/librustc_macros/src/hash_stable.rs @@ -1,7 +1,6 @@ use proc_macro2::{self, Ident}; use quote::quote; use syn::{self, parse_quote, Meta, NestedMeta}; -use synstructure; struct Attributes { ignore: bool, diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs index 51b0b5bc7cb0b..4583e244f493d 100644 --- a/src/librustc_mir_build/build/expr/into.rs +++ b/src/librustc_mir_build/build/expr/into.rs @@ -376,7 +376,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { TerminatorKind::Yield { value, resume, - resume_arg: destination.clone(), + resume_arg: *destination, drop: cleanup, }, ); diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index f900ae45b94d6..7995125524314 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -649,7 +649,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } PatKind::Or { ref pats } => { - self.visit_bindings(&pats[0], pattern_user_ty.clone(), f); + self.visit_bindings(&pats[0], pattern_user_ty, f); } } } diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index a0b8415b3e17e..bd0b189d4fd4d 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -314,9 +314,6 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke Nonterminal::NtItem(ref item) => { prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span) } - Nonterminal::NtTraitItem(ref item) | Nonterminal::NtImplItem(ref item) => { - prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span) - } Nonterminal::NtIdent(ident, is_raw) => { Some(tokenstream::TokenTree::token(token::Ident(ident.name, is_raw), ident.span).into()) } diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 5b2e5a9e454ea..d7d6fcd05b795 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -632,16 +632,10 @@ impl<'a> Parser<'a> { } pub fn parse_impl_item(&mut self) -> PResult<'a, Option>>> { - maybe_whole!(self, NtImplItem, |x| Some(Some(x))); self.parse_assoc_item(|_| true) } pub fn parse_trait_item(&mut self) -> PResult<'a, Option>>> { - maybe_whole!(self, NtTraitItem, |x| Some(Some(x))); - // This is somewhat dubious; We don't want to allow - // param names to be left off if there is a definition... - // - // We don't allow param names to be left off in edition 2018. self.parse_assoc_item(|t| t.span.rust_2018()) } @@ -834,8 +828,6 @@ impl<'a> Parser<'a> { /// Parses a foreign item (one in an `extern { ... }` block). pub fn parse_foreign_item(&mut self) -> PResult<'a, Option>>> { - maybe_whole!(self, NtForeignItem, |item| Some(Some(item))); - Ok(self.parse_item_(|_| true)?.map(|Item { attrs, id, span, vis, ident, kind, tokens }| { let kind = match kind { ItemKind::Mac(a) => ForeignItemKind::Macro(a), diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 97708d91d7e2a..b8e5ea97f4e47 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -893,19 +893,17 @@ impl Hash for Ident { impl fmt::Debug for Ident { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.is_raw_guess() { - write!(f, "r#")?; - } - write!(f, "{}{:?}", self.name, self.span.ctxt()) + fmt::Display::fmt(self, f)?; + fmt::Debug::fmt(&self.span.ctxt(), f) } } +/// This implementation is supposed to be used in error messages, so it's expected to be identical +/// to printing the original identifier token written in source code (`token_to_string`), +/// except that AST identifiers don't keep the rawness flag, so we have to guess it. impl fmt::Display for Ident { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.is_raw_guess() { - write!(f, "r#")?; - } - fmt::Display::fmt(&self.name, f) + fmt::Display::fmt(&IdentPrinter::new(self.name, self.is_raw_guess(), None), f) } } @@ -929,6 +927,59 @@ impl UseSpecializedDecodable for Ident { } } +/// This is the most general way to print identifiers. +/// AST pretty-printer is used as a fallback for turning AST structures into token streams for +/// proc macros. Additionally, proc macros may stringify their input and expect it survive the +/// stringification (especially true for proc macro derives written between Rust 1.15 and 1.30). +/// So we need to somehow pretty-print `$crate` in a way preserving at least some of its +/// hygiene data, most importantly name of the crate it refers to. +/// As a result we print `$crate` as `crate` if it refers to the local crate +/// and as `::other_crate_name` if it refers to some other crate. +/// Note, that this is only done if the ident token is printed from inside of AST pretty-pringing, +/// but not otherwise. Pretty-printing is the only way for proc macros to discover token contents, +/// so we should not perform this lossy conversion if the top level call to the pretty-printer was +/// done for a token stream or a single token. +pub struct IdentPrinter { + symbol: Symbol, + is_raw: bool, + /// Span used for retrieving the crate name to which `$crate` refers to, + /// if this field is `None` then the `$crate` conversion doesn't happen. + convert_dollar_crate: Option, +} + +impl IdentPrinter { + /// The most general `IdentPrinter` constructor. Do not use this. + pub fn new(symbol: Symbol, is_raw: bool, convert_dollar_crate: Option) -> IdentPrinter { + IdentPrinter { symbol, is_raw, convert_dollar_crate } + } + + /// This implementation is supposed to be used when printing identifiers + /// as a part of pretty-printing for larger AST pieces. + /// Do not use this either. + pub fn for_ast_ident(ident: Ident, is_raw: bool) -> IdentPrinter { + IdentPrinter::new(ident.name, is_raw, Some(ident.span)) + } +} + +impl fmt::Display for IdentPrinter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.is_raw { + f.write_str("r#")?; + } else { + if self.symbol == kw::DollarCrate { + if let Some(span) = self.convert_dollar_crate { + let converted = span.ctxt().dollar_crate_name(); + if !converted.is_path_segment_keyword() { + f.write_str("::")?; + } + return fmt::Display::fmt(&converted, f); + } + } + } + fmt::Display::fmt(&self.symbol, f) + } +} + /// An interned string. /// /// Internally, a `Symbol` is implemented as an index, and all operations diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 799585ffc0acf..7b3c702b929c0 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -233,12 +233,12 @@ #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] -#![feature(atomic_mut_ptr)] #![feature(arbitrary_self_types)] #![feature(array_error_internals)] #![feature(asm)] #![feature(assoc_int_consts)] #![feature(associated_type_bounds)] +#![feature(atomic_mut_ptr)] #![feature(box_syntax)] #![feature(c_variadic)] #![feature(cfg_target_has_atomic)] @@ -551,6 +551,9 @@ pub use core::{ trace_macros, }; +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use core::primitive; + // Include a number of private modules that exist solely to provide // the rustdoc documentation for primitive types. Using `include!` // because rustdoc only looks for these modules at the crate level. diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 19c705fa99753..62ff4f5183a70 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2441,6 +2441,13 @@ impl Item { } } +impl Item { + pub fn into_item(self) -> Item { + let Item { attrs, id, span, vis, ident, kind, tokens } = self; + Item { attrs, id, span, vis, ident, kind: kind.into_item_kind(), tokens } + } +} + /// `extern` qualifier on a function item or function type. #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] pub enum Extern { @@ -2617,6 +2624,10 @@ impl ItemKind { } } +pub trait IntoItemKind { + fn into_item_kind(self) -> ItemKind; +} + // FIXME(Centril): These definitions should be unmerged; // see https://github.com/rust-lang/rust/pull/69194#discussion_r379899975 pub type ForeignItem = Item; @@ -2656,3 +2667,15 @@ impl AssocItemKind { } } } + +impl IntoItemKind for AssocItemKind { + fn into_item_kind(self) -> ItemKind { + match self { + AssocItemKind::Const(a, b, c) => ItemKind::Const(a, b, c), + AssocItemKind::Static(a, b, c) => ItemKind::Static(a, b, c), + AssocItemKind::Fn(a, b, c, d) => ItemKind::Fn(a, b, c, d), + AssocItemKind::TyAlias(a, b, c, d) => ItemKind::TyAlias(a, b, c, d), + AssocItemKind::Macro(a) => ItemKind::Mac(a), + } + } +} diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 05bb07cd4b90a..b3abd4fc755e4 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -711,20 +711,7 @@ pub fn noop_visit_interpolated(nt: &mut token::Nonterminal, vis: } token::NtPath(path) => vis.visit_path(path), token::NtTT(tt) => vis.visit_tt(tt), - token::NtImplItem(item) => visit_clobber(item, |item| { - // See reasoning above. - vis.flat_map_impl_item(item).expect_one("expected visitor to produce exactly one item") - }), - token::NtTraitItem(item) => visit_clobber(item, |item| { - // See reasoning above. - vis.flat_map_trait_item(item).expect_one("expected visitor to produce exactly one item") - }), token::NtVis(visib) => vis.visit_vis(visib), - token::NtForeignItem(item) => visit_clobber(item, |item| { - // See reasoning above. - vis.flat_map_foreign_item(item) - .expect_one("expected visitor to produce exactly one item") - }), } } diff --git a/src/libsyntax/token.rs b/src/libsyntax/token.rs index 6eeee49881579..52bf50604fb30 100644 --- a/src/libsyntax/token.rs +++ b/src/libsyntax/token.rs @@ -712,12 +712,6 @@ pub enum Nonterminal { NtPath(ast::Path), NtVis(ast::Visibility), NtTT(TokenTree), - // Used only for passing items to proc macro attributes (they are not - // strictly necessary for that, `Annotatable` can be converted into - // tokens directly, but doing that naively regresses pretty-printing). - NtTraitItem(P), - NtImplItem(P), - NtForeignItem(P), } // `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger. @@ -755,9 +749,6 @@ impl fmt::Debug for Nonterminal { NtMeta(..) => f.pad("NtMeta(..)"), NtPath(..) => f.pad("NtPath(..)"), NtTT(..) => f.pad("NtTT(..)"), - NtImplItem(..) => f.pad("NtImplItem(..)"), - NtTraitItem(..) => f.pad("NtTraitItem(..)"), - NtForeignItem(..) => f.pad("NtForeignItem(..)"), NtVis(..) => f.pad("NtVis(..)"), NtLifetime(..) => f.pad("NtLifetime(..)"), } diff --git a/src/test/ui/proc-macro/trait-fn-args-2015.rs b/src/test/ui/proc-macro/trait-fn-args-2015.rs new file mode 100644 index 0000000000000..3a448d4b2201d --- /dev/null +++ b/src/test/ui/proc-macro/trait-fn-args-2015.rs @@ -0,0 +1,14 @@ +// Unnamed arguments in trait functions can be passed through proc macros on 2015 edition. + +// check-pass +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +trait Tr { + #[identity_attr] + fn method(u8); +} + +fn main() {} diff --git a/src/test/ui/resolve/resolve-primitive-fallback.stderr b/src/test/ui/resolve/resolve-primitive-fallback.stderr index 6d61d2f16cafa..9d381a8a94e3f 100644 --- a/src/test/ui/resolve/resolve-primitive-fallback.stderr +++ b/src/test/ui/resolve/resolve-primitive-fallback.stderr @@ -9,6 +9,11 @@ error[E0412]: cannot find type `u8` in the crate root | LL | let _: ::u8; | ^^ not found in the crate root + | +help: possible candidate is found in another module, you can import it into scope + | +LL | use std::primitive::u8; + | error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/resolve-primitive-fallback.rs:3:5 diff --git a/src/test/ui/shadow-bool.rs b/src/test/ui/shadow-bool.rs new file mode 100644 index 0000000000000..f290a329eaac2 --- /dev/null +++ b/src/test/ui/shadow-bool.rs @@ -0,0 +1,18 @@ +// check-pass + +mod bar { + pub trait QueryId { + const SOME_PROPERTY: bool; + } +} + +use bar::QueryId; + +#[allow(non_camel_case_types)] +pub struct bool; + +impl QueryId for bool { + const SOME_PROPERTY: core::primitive::bool = true; +} + +fn main() {} diff --git a/src/test/ui/unused/unused-attr-crate.rs b/src/test/ui/unused/unused-attr-crate.rs new file mode 100644 index 0000000000000..adb939e9b400e --- /dev/null +++ b/src/test/ui/unused/unused-attr-crate.rs @@ -0,0 +1,13 @@ +#![deny(unused_attributes)] + +#![feature(naked_functions)] +#![feature(track_caller)] + +#![used] //~ ERROR unused attribute +#![non_exhaustive] //~ ERROR unused attribute +#![inline] //~ ERROR unused attribute +#![target_feature(enable = "")] //~ ERROR unused attribute +#![naked] //~ ERROR unused attribute +#![track_caller] //~ ERROR unused attribute + +fn main() {} diff --git a/src/test/ui/unused/unused-attr-crate.stderr b/src/test/ui/unused/unused-attr-crate.stderr new file mode 100644 index 0000000000000..620a3ea5315cb --- /dev/null +++ b/src/test/ui/unused/unused-attr-crate.stderr @@ -0,0 +1,44 @@ +error: unused attribute + --> $DIR/unused-attr-crate.rs:6:1 + | +LL | #![used] + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-attr-crate.rs:1:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-crate.rs:7:1 + | +LL | #![non_exhaustive] + | ^^^^^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-crate.rs:8:1 + | +LL | #![inline] + | ^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-crate.rs:9:1 + | +LL | #![target_feature(enable = "")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-crate.rs:10:1 + | +LL | #![naked] + | ^^^^^^^^^ + +error: unused attribute + --> $DIR/unused-attr-crate.rs:11:1 + | +LL | #![track_caller] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors +