diff options
Diffstat (limited to 'compiler')
53 files changed, 299 insertions, 212 deletions
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index b311f9fdcb9..90bfb01d6c7 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -771,7 +771,7 @@ impl fmt::Display for NonterminalKind { } impl Nonterminal { - fn span(&self) -> Span { + pub fn span(&self) -> Span { match self { NtItem(item) => item.span, NtBlock(block) => block.span, diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 0550f53a96f..00354b42ebb 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -1,15 +1,15 @@ //! # Token Streams //! //! `TokenStream`s represent syntactic objects before they are converted into ASTs. -//! A `TokenStream` is, roughly speaking, a sequence (eg stream) of `TokenTree`s, -//! which are themselves a single `Token` or a `Delimited` subsequence of tokens. +//! A `TokenStream` is, roughly speaking, a sequence of [`TokenTree`]s, +//! which are themselves a single [`Token`] or a `Delimited` subsequence of tokens. //! //! ## Ownership //! //! `TokenStream`s are persistent data structures constructed as ropes with reference //! counted-children. In general, this means that calling an operation on a `TokenStream` //! (such as `slice`) produces an entirely new `TokenStream` from the borrowed reference to -//! the original. This essentially coerces `TokenStream`s into 'views' of their subparts, +//! the original. This essentially coerces `TokenStream`s into "views" of their subparts, //! and a borrowed `TokenStream` is sufficient to build an owned `TokenStream` without taking //! ownership of the original. @@ -24,9 +24,9 @@ use smallvec::{smallvec, SmallVec}; use std::{fmt, iter, mem}; -/// When the main rust parser encounters a syntax-extension invocation, it -/// parses the arguments to the invocation as a token-tree. This is a very -/// loose structure, such that all sorts of different AST-fragments can +/// When the main Rust parser encounters a syntax-extension invocation, it +/// parses the arguments to the invocation as a token tree. This is a very +/// loose structure, such that all sorts of different AST fragments can /// be passed to syntax extensions using a uniform type. /// /// If the syntax extension is an MBE macro, it will attempt to match its @@ -38,9 +38,9 @@ use std::{fmt, iter, mem}; /// Nothing special happens to misnamed or misplaced `SubstNt`s. #[derive(Debug, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)] pub enum TokenTree { - /// A single token + /// A single token. Token(Token), - /// A delimited sequence of token trees + /// A delimited sequence of token trees. Delimited(DelimSpan, DelimToken, TokenStream), } @@ -62,7 +62,7 @@ where } impl TokenTree { - /// Checks if this TokenTree is equal to the other, regardless of span information. + /// Checks if this `TokenTree` is equal to the other, regardless of span information. pub fn eq_unspanned(&self, other: &TokenTree) -> bool { match (self, other) { (TokenTree::Token(token), TokenTree::Token(token2)) => token.kind == token2.kind, @@ -73,7 +73,7 @@ impl TokenTree { } } - /// Retrieves the TokenTree's span. + /// Retrieves the `TokenTree`'s span. pub fn span(&self) -> Span { match self { TokenTree::Token(token) => token.span, @@ -140,7 +140,7 @@ impl CreateTokenStream for TokenStream { } } -/// A lazy version of `TokenStream`, which defers creation +/// A lazy version of [`TokenStream`], which defers creation /// of an actual `TokenStream` until it is needed. /// `Box` is here only to reduce the structure size. #[derive(Clone)] @@ -188,11 +188,12 @@ impl<CTX> HashStable<CTX> for LazyTokenStream { } } -/// A `TokenStream` is an abstract sequence of tokens, organized into `TokenTree`s. +/// A `TokenStream` is an abstract sequence of tokens, organized into [`TokenTree`]s. /// /// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s /// instead of a representation of the abstract syntax tree. -/// Today's `TokenTree`s can still contain AST via `token::Interpolated` for back-compat. +/// Today's `TokenTree`s can still contain AST via `token::Interpolated` for +/// backwards compatability. #[derive(Clone, Debug, Default, Encodable, Decodable)] pub struct TokenStream(pub(crate) Lrc<Vec<TreeAndSpacing>>); @@ -429,7 +430,7 @@ impl TokenStreamBuilder { } } -/// By-reference iterator over a `TokenStream`. +/// By-reference iterator over a [`TokenStream`]. #[derive(Clone)] pub struct CursorRef<'t> { stream: &'t TokenStream, @@ -457,8 +458,8 @@ impl<'t> Iterator for CursorRef<'t> { } } -/// Owning by-value iterator over a `TokenStream`. -/// FIXME: Many uses of this can be replaced with by-reference iterator to avoid clones. +/// Owning by-value iterator over a [`TokenStream`]. +// FIXME: Many uses of this can be replaced with by-reference iterator to avoid clones. #[derive(Clone)] pub struct Cursor { pub stream: TokenStream, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index fe96e1c5c04..ab9861b85ab 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -206,8 +206,7 @@ pub trait ResolverAstLowering { ) -> LocalDefId; } -type NtToTokenstream = - fn(&Nonterminal, &ParseSess, Span, CanSynthesizeMissingTokens) -> TokenStream; +type NtToTokenstream = fn(&Nonterminal, &ParseSess, CanSynthesizeMissingTokens) -> TokenStream; /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree, /// and if so, what meaning it has. @@ -417,12 +416,7 @@ impl<'a> TokenStreamLowering<'a> { fn lower_token(&mut self, token: Token) -> TokenStream { match token.kind { token::Interpolated(nt) => { - let tts = (self.nt_to_tokenstream)( - &nt, - self.parse_sess, - token.span, - self.synthesize_tokens, - ); + let tts = (self.nt_to_tokenstream)(&nt, self.parse_sess, self.synthesize_tokens); TokenTree::Delimited( DelimSpan::from_single(token.span), DelimToken::NoDelim, diff --git a/compiler/rustc_ast_pretty/src/pprust/mod.rs b/compiler/rustc_ast_pretty/src/pprust/mod.rs index b34ea41ab55..b88699f6ee1 100644 --- a/compiler/rustc_ast_pretty/src/pprust/mod.rs +++ b/compiler/rustc_ast_pretty/src/pprust/mod.rs @@ -8,11 +8,6 @@ use rustc_ast as ast; use rustc_ast::token::{Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; -pub fn nonterminal_to_string_no_extra_parens(nt: &Nonterminal) -> String { - let state = State::without_insert_extra_parens(); - state.nonterminal_to_string(nt) -} - pub fn nonterminal_to_string(nt: &Nonterminal) -> String { State::new().nonterminal_to_string(nt) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 0e4f2798bd3..ca816ef6769 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -88,13 +88,6 @@ pub struct State<'a> { comments: Option<Comments<'a>>, ann: &'a (dyn PpAnn + 'a), is_expanded: bool, - // If `true`, additional parenthesis (separate from `ExprKind::Paren`) - // are inserted to ensure that proper precedence is preserved - // in the pretty-printed output. - // - // This is usually `true`, except when performing the pretty-print/reparse - // check in `nt_to_tokenstream` - insert_extra_parens: bool, } crate const INDENT_UNIT: usize = 4; @@ -115,7 +108,6 @@ pub fn print_crate<'a>( comments: Some(Comments::new(sm, filename, input)), ann, is_expanded, - insert_extra_parens: true, }; if is_expanded && !krate.attrs.iter().any(|attr| attr.has_name(sym::no_core)) { @@ -235,7 +227,6 @@ impl std::ops::DerefMut for State<'_> { } pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::DerefMut { - fn insert_extra_parens(&self) -> bool; fn comments(&mut self) -> &mut Option<Comments<'a>>; fn print_ident(&mut self, ident: Ident); fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool); @@ -819,16 +810,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere fn to_string(&self, f: impl FnOnce(&mut State<'_>)) -> String { let mut printer = State::new(); - printer.insert_extra_parens = self.insert_extra_parens(); f(&mut printer); printer.s.eof() } } impl<'a> PrintState<'a> for State<'a> { - fn insert_extra_parens(&self) -> bool { - self.insert_extra_parens - } fn comments(&mut self) -> &mut Option<Comments<'a>> { &mut self.comments } @@ -865,17 +852,7 @@ impl<'a> PrintState<'a> for State<'a> { impl<'a> State<'a> { pub fn new() -> State<'a> { - State { - s: pp::mk_printer(), - comments: None, - ann: &NoAnn, - is_expanded: false, - insert_extra_parens: true, - } - } - - pub(super) fn without_insert_extra_parens() -> State<'a> { - State { insert_extra_parens: false, ..State::new() } + State { s: pp::mk_printer(), comments: None, ann: &NoAnn, is_expanded: false } } // Synthesizes a comment that was not textually present in the original source @@ -1680,8 +1657,7 @@ impl<'a> State<'a> { } /// Prints `expr` or `(expr)` when `needs_par` holds. - fn print_expr_cond_paren(&mut self, expr: &ast::Expr, mut needs_par: bool) { - needs_par &= self.insert_extra_parens; + fn print_expr_cond_paren(&mut self, expr: &ast::Expr, needs_par: bool) { if needs_par { self.popen(); } diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 3fc56eecdd0..07fde27b5a3 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -9,7 +9,7 @@ use rustc_codegen_ssa::{ }; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::Ty; -use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size}; +use rustc_target::abi::{Align, Endian, HasDataLayout, LayoutOf, Size}; fn round_pointer_up_to_alignment( bx: &mut Builder<'a, 'll, 'tcx>, @@ -52,7 +52,7 @@ fn emit_direct_ptr_va_arg( let next = bx.inbounds_gep(addr, &[full_direct_size]); bx.store(next, va_list_addr, bx.tcx().data_layout.pointer_align.abi); - if size.bytes() < slot_size.bytes() && &*bx.tcx().sess.target.endian == "big" { + if size.bytes() < slot_size.bytes() && bx.tcx().sess.target.endian == Endian::Big { let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32); let adjusted = bx.inbounds_gep(addr, &[adjusted_size]); (bx.bitcast(adjusted, bx.cx().type_ptr_to(llty)), addr_align) @@ -105,7 +105,7 @@ fn emit_aapcs_va_arg( let mut end = bx.build_sibling_block("va_arg.end"); let zero = bx.const_i32(0); let offset_align = Align::from_bytes(4).unwrap(); - assert!(&*bx.tcx().sess.target.endian == "little"); + assert_eq!(bx.tcx().sess.target.endian, Endian::Little); let gr_type = target_ty.is_any_ptr() || target_ty.is_integral(); let (reg_off, reg_top_index, slot_size) = if gr_type { diff --git a/compiler/rustc_error_codes/src/error_codes/E0435.md b/compiler/rustc_error_codes/src/error_codes/E0435.md index 424e5ce1e2e..798a20d48b6 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0435.md +++ b/compiler/rustc_error_codes/src/error_codes/E0435.md @@ -7,6 +7,12 @@ let foo = 42; let a: [u8; foo]; // error: attempt to use a non-constant value in a constant ``` +'constant' means 'a compile-time value'. + +More details can be found in the [Variables and Mutability] section of the book. + +[Variables and Mutability]: https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants + To fix this error, please replace the value with a constant. Example: ``` diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 887e12b46f6..b2ba720e0d7 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -141,7 +141,7 @@ impl Annotatable { } crate fn into_tokens(self, sess: &ParseSess) -> TokenStream { - nt_to_tokenstream(&self.into_nonterminal(), sess, DUMMY_SP, CanSynthesizeMissingTokens::No) + nt_to_tokenstream(&self.into_nonterminal(), sess, CanSynthesizeMissingTokens::No) } pub fn expect_item(self) -> P<ast::Item> { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 1453627f6e1..fa80a20dc8b 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -743,7 +743,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { AttrStyle::Inner => rustc_parse::fake_token_stream( &self.cx.sess.parse_sess, &item.into_nonterminal(), - span, ), }; let attr_item = attr.unwrap_normal_item(); diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index e8e098b6212..02129e9b5e5 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -94,12 +94,7 @@ impl MultiItemModifier for ProcMacroDerive { let input = if item.pretty_printing_compatibility_hack() { TokenTree::token(token::Interpolated(Lrc::new(item)), DUMMY_SP).into() } else { - nt_to_tokenstream( - &item, - &ecx.sess.parse_sess, - DUMMY_SP, - CanSynthesizeMissingTokens::Yes, - ) + nt_to_tokenstream(&item, &ecx.sess.parse_sess, CanSynthesizeMissingTokens::Yes) }; let server = proc_macro_server::Rustc::new(ecx); diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 02ae842675f..b6195d3bbc4 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -179,7 +179,7 @@ impl FromInternal<(TreeAndSpacing, &'_ ParseSess, &'_ mut Vec<Self>)> { TokenTree::Ident(Ident::new(sess, name.name, is_raw, name.span)) } else { - let stream = nt_to_tokenstream(&nt, sess, span, CanSynthesizeMissingTokens::No); + let stream = nt_to_tokenstream(&nt, sess, CanSynthesizeMissingTokens::No); TokenTree::Group(Group { delimiter: Delimiter::None, stream, diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index ddd3827c81d..a9aa192bbcc 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -138,9 +138,6 @@ impl std::ops::DerefMut for State<'_> { } impl<'a> PrintState<'a> for State<'a> { - fn insert_extra_parens(&self) -> bool { - true - } fn comments(&mut self) -> &mut Option<Comments<'a>> { &mut self.comments } diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs index e185ee24d17..c86122f8939 100644 --- a/compiler/rustc_incremental/src/persist/file_format.rs +++ b/compiler/rustc_incremental/src/persist/file_format.rs @@ -52,11 +52,11 @@ pub fn read_file( path: &Path, nightly_build: bool, ) -> io::Result<Option<(Vec<u8>, usize)>> { - if !path.exists() { - return Ok(None); - } - - let data = fs::read(path)?; + let data = match fs::read(path) { + Ok(data) => data, + Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(None), + Err(err) => return Err(err), + }; let mut file = io::Cursor::new(data); diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 9fdf0a56d9d..7a1976bed4b 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -922,22 +922,24 @@ fn all_except_most_recent( /// before passing it to std::fs::remove_dir_all(). This will convert the path /// into the '\\?\' format, which supports much longer paths. fn safe_remove_dir_all(p: &Path) -> io::Result<()> { - if p.exists() { - let canonicalized = p.canonicalize()?; - std_fs::remove_dir_all(canonicalized) - } else { - Ok(()) - } + let canonicalized = match std_fs::canonicalize(p) { + Ok(canonicalized) => canonicalized, + Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()), + Err(err) => return Err(err), + }; + + std_fs::remove_dir_all(canonicalized) } fn safe_remove_file(p: &Path) -> io::Result<()> { - if p.exists() { - let canonicalized = p.canonicalize()?; - match std_fs::remove_file(canonicalized) { - Err(ref err) if err.kind() == io::ErrorKind::NotFound => Ok(()), - result => result, - } - } else { - Ok(()) + let canonicalized = match std_fs::canonicalize(p) { + Ok(canonicalized) => canonicalized, + Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()), + Err(err) => return Err(err), + }; + + match std_fs::remove_file(canonicalized) { + Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(()), + result => result, } } diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 102a77e8e79..2169f5a89e1 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -6,6 +6,7 @@ use rustc_serialize::opaque::Encoder; use rustc_serialize::Encodable as RustcEncodable; use rustc_session::Session; use std::fs; +use std::io; use std::path::PathBuf; use super::data::*; @@ -101,19 +102,18 @@ where // Note: It's important that we actually delete the old file and not just // truncate and overwrite it, since it might be a shared hard-link, the // underlying data of which we don't want to modify - if path_buf.exists() { - match fs::remove_file(&path_buf) { - Ok(()) => { - debug!("save: remove old file"); - } - Err(err) => { - sess.err(&format!( - "unable to delete old dep-graph at `{}`: {}", - path_buf.display(), - err - )); - return; - } + match fs::remove_file(&path_buf) { + Ok(()) => { + debug!("save: remove old file"); + } + Err(err) if err.kind() == io::ErrorKind::NotFound => (), + Err(err) => { + sess.err(&format!( + "unable to delete old dep-graph at `{}`: {}", + path_buf.display(), + err + )); + return; } } diff --git a/compiler/rustc_lexer/src/cursor.rs b/compiler/rustc_lexer/src/cursor.rs index c0045d3f79b..297f3d19ca1 100644 --- a/compiler/rustc_lexer/src/cursor.rs +++ b/compiler/rustc_lexer/src/cursor.rs @@ -33,7 +33,7 @@ impl<'a> Cursor<'a> { #[cfg(not(debug_assertions))] { - '\0' + EOF_CHAR } } diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index f810f6a56a5..698c2521596 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -1,7 +1,6 @@ use crate::dep_graph::{dep_constructor, DepNode, WorkProduct, WorkProductId}; use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt}; -use rustc_attr::InlineAttr; use rustc_data_structures::base_n; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; @@ -79,14 +78,6 @@ impl<'tcx> MonoItem<'tcx> { } pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode { - let generate_cgu_internal_copies = tcx - .sess - .opts - .debugging_opts - .inline_in_all_cgus - .unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No) - && !tcx.sess.link_dead_code(); - match *self { MonoItem::Fn(ref instance) => { let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id); @@ -99,21 +90,26 @@ impl<'tcx> MonoItem<'tcx> { return InstantiationMode::GloballyShared { may_conflict: false }; } + let generate_cgu_internal_copies = tcx + .sess + .opts + .debugging_opts + .inline_in_all_cgus + .unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No) + && !tcx.sess.link_dead_code(); + // At this point we don't have explicit linkage and we're an - // inlined function. If we're inlining into all CGUs then we'll - // be creating a local copy per CGU. + // inlined function. If we should generate local copies for each CGU, + // then return `LocalCopy`, otherwise we'll just generate one copy + // and share it with all CGUs in this crate. if generate_cgu_internal_copies { - return InstantiationMode::LocalCopy; - } - - // Finally, if this is `#[inline(always)]` we're sure to respect - // that with an inline copy per CGU, but otherwise we'll be - // creating one copy of this `#[inline]` function which may - // conflict with upstream crates as it could be an exported - // symbol. - match tcx.codegen_fn_attrs(instance.def_id()).inline { - InlineAttr::Always => InstantiationMode::LocalCopy, - _ => InstantiationMode::GloballyShared { may_conflict: true }, + InstantiationMode::LocalCopy + } else { + // Finally, if we've reached this point, then we should optimize for + // compilation speed. In that regard, we will ignore any `#[inline]` + // annotations on the function and simply codegen it as usual. This could + // conflict with upstream crates as it could be an exported symbol. + InstantiationMode::GloballyShared { may_conflict: true } } } MonoItem::Static(..) | MonoItem::GlobalAsm(..) => { diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index df2f69df520..52350c5d078 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -41,6 +41,15 @@ impl<'tcx> MirPass<'tcx> for Inline { return; } + if tcx.sess.opts.debugging_opts.instrument_coverage { + // Since `Inline` happens after `InstrumentCoverage`, the function-specific coverage + // counters can be invalidated, such as by merging coverage counter statements from + // a pre-inlined function into a different function. This kind of change is invalid, + // so inlining must be skipped. Note: This check is performed here so inlining can + // be disabled without preventing other optimizations (regardless of `mir_opt_level`). + return; + } + if inline(tcx, body) { debug!("running simplify cfg on {:?}", body.source); CfgSimplifier::new(body).simplify(); diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 9abffbacfc3..0da9cd3fe5e 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -236,7 +236,6 @@ pub fn parse_in<'a, T>( pub fn nt_to_tokenstream( nt: &Nonterminal, sess: &ParseSess, - span: Span, synthesize_tokens: CanSynthesizeMissingTokens, ) -> TokenStream { // A `Nonterminal` is often a parsed AST item. At this point we now @@ -256,11 +255,9 @@ pub fn nt_to_tokenstream( |tokens: Option<&LazyTokenStream>| tokens.as_ref().map(|t| t.create_token_stream()); let tokens = match *nt { - Nonterminal::NtItem(ref item) => { - prepend_attrs(sess, &item.attrs, nt, span, item.tokens.as_ref()) - } + Nonterminal::NtItem(ref item) => prepend_attrs(sess, &item.attrs, nt, item.tokens.as_ref()), Nonterminal::NtBlock(ref block) => convert_tokens(block.tokens.as_ref()), - Nonterminal::NtStmt(ref stmt) => prepend_attrs(sess, stmt.attrs(), nt, span, stmt.tokens()), + Nonterminal::NtStmt(ref stmt) => prepend_attrs(sess, stmt.attrs(), nt, stmt.tokens()), Nonterminal::NtPat(ref pat) => convert_tokens(pat.tokens.as_ref()), Nonterminal::NtTy(ref ty) => convert_tokens(ty.tokens.as_ref()), Nonterminal::NtIdent(ident, is_raw) => { @@ -277,31 +274,29 @@ pub fn nt_to_tokenstream( if expr.tokens.is_none() { debug!("missing tokens for expr {:?}", expr); } - prepend_attrs(sess, &expr.attrs, nt, span, expr.tokens.as_ref()) + prepend_attrs(sess, &expr.attrs, nt, expr.tokens.as_ref()) } }; if let Some(tokens) = tokens { return tokens; } else if matches!(synthesize_tokens, CanSynthesizeMissingTokens::Yes) { - return fake_token_stream(sess, nt, span); + return fake_token_stream(sess, nt); } else { - let pretty = rustc_ast_pretty::pprust::nonterminal_to_string_no_extra_parens(&nt); - panic!("Missing tokens at {:?} for nt {:?}", span, pretty); + panic!("Missing tokens for nt {:?}", pprust::nonterminal_to_string(nt)); } } -pub fn fake_token_stream(sess: &ParseSess, nt: &Nonterminal, span: Span) -> TokenStream { +pub fn fake_token_stream(sess: &ParseSess, nt: &Nonterminal) -> TokenStream { let source = pprust::nonterminal_to_string(nt); let filename = FileName::macro_expansion_source_code(&source); - parse_stream_from_source_str(filename, source, sess, Some(span)) + parse_stream_from_source_str(filename, source, sess, Some(nt.span())) } fn prepend_attrs( sess: &ParseSess, attrs: &[ast::Attribute], nt: &Nonterminal, - span: Span, tokens: Option<&tokenstream::LazyTokenStream>, ) -> Option<tokenstream::TokenStream> { if attrs.is_empty() { @@ -312,7 +307,7 @@ fn prepend_attrs( // FIXME: Correctly handle tokens for inner attributes. // For now, we fall back to reparsing the original AST node if attr.style == ast::AttrStyle::Inner { - return Some(fake_token_stream(sess, nt, span)); + return Some(fake_token_stream(sess, nt)); } builder.push(attr.tokens()); } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e49b1a54e9b..4fcc9edb7d9 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -220,7 +220,22 @@ impl<'a> Parser<'a> { let info = if self.eat_keyword(kw::Use) { // USE ITEM let tree = self.parse_use_tree()?; - self.expect_semi()?; + + // If wildcard or glob-like brace syntax doesn't have `;`, + // the user may not know `*` or `{}` should be the last. + if let Err(mut e) = self.expect_semi() { + match tree.kind { + UseTreeKind::Glob => { + e.note("the wildcard token must be last on the path").emit(); + } + UseTreeKind::Nested(..) => { + e.note("glob-like brace syntax must be last on the path").emit(); + } + _ => (), + } + return Err(e); + } + (Ident::invalid(), ItemKind::Use(P(tree))) } else if self.check_fn_front_matter() { // FUNCTION ITEM diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 420c002c5fc..a6a61ffc5da 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -359,7 +359,7 @@ impl CheckAttrVisitor<'tcx> { return false; } let item_name = self.tcx.hir().name(hir_id); - if item_name.to_string() == doc_alias { + if &*item_name.as_str() == doc_alias { self.tcx .sess .struct_span_err( diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 809de9beff6..6a181dbab5a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -398,13 +398,19 @@ impl<'a> Resolver<'a> { err.help("use the `|| { ... }` closure form instead"); err } - ResolutionError::AttemptToUseNonConstantValueInConstant => { + ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg) => { let mut err = struct_span_err!( self.session, span, E0435, "attempt to use a non-constant value in a constant" ); + err.span_suggestion( + ident.span, + &sugg, + "".to_string(), + Applicability::MaybeIncorrect, + ); err.span_label(span, "non-constant value"); err } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2e738ce8dac..4d956e7f0d2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -92,6 +92,12 @@ crate enum HasGenericParams { No, } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +crate enum ConstantItemKind { + Const, + Static, +} + /// The rib kind restricts certain accesses, /// e.g. to a `Res::Local` of an outer item. #[derive(Copy, Clone, Debug)] @@ -119,7 +125,7 @@ crate enum RibKind<'a> { /// /// The `bool` indicates if this constant may reference generic parameters /// and is used to only allow generic parameters to be used in trivial constant expressions. - ConstantItemRibKind(bool), + ConstantItemRibKind(bool, Option<(Ident, ConstantItemKind)>), /// We passed through a module. ModuleRibKind(Module<'a>), @@ -145,7 +151,7 @@ impl RibKind<'_> { NormalRibKind | ClosureOrAsyncRibKind | FnItemRibKind - | ConstantItemRibKind(_) + | ConstantItemRibKind(..) | ModuleRibKind(_) | MacroDefinition(_) | ConstParamTyRibKind => false, @@ -634,7 +640,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { // Note that we might not be inside of an repeat expression here, // but considering that `IsRepeatExpr` is only relevant for // non-trivial constants this is doesn't matter. - self.with_constant_rib(IsRepeatExpr::No, true, |this| { + self.with_constant_rib(IsRepeatExpr::No, true, None, |this| { this.smart_resolve_path( ty.id, qself.as_ref(), @@ -843,7 +849,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { | ClosureOrAsyncRibKind | FnItemRibKind | ItemRibKind(..) - | ConstantItemRibKind(_) + | ConstantItemRibKind(..) | ModuleRibKind(..) | ForwardTyParamBanRibKind | ConstParamTyRibKind => { @@ -970,6 +976,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.with_constant_rib( IsRepeatExpr::No, true, + None, |this| this.visit_expr(expr), ); } @@ -1012,11 +1019,19 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.with_item_rib(HasGenericParams::No, |this| { this.visit_ty(ty); if let Some(expr) = expr { + let constant_item_kind = match item.kind { + ItemKind::Const(..) => ConstantItemKind::Const, + ItemKind::Static(..) => ConstantItemKind::Static, + _ => unreachable!(), + }; // We already forbid generic params because of the above item rib, // so it doesn't matter whether this is a trivial constant. - this.with_constant_rib(IsRepeatExpr::No, true, |this| { - this.visit_expr(expr) - }); + this.with_constant_rib( + IsRepeatExpr::No, + true, + Some((item.ident, constant_item_kind)), + |this| this.visit_expr(expr), + ); } }); } @@ -1118,15 +1133,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { &mut self, is_repeat: IsRepeatExpr, is_trivial: bool, + item: Option<(Ident, ConstantItemKind)>, f: impl FnOnce(&mut Self), ) { debug!("with_constant_rib: is_repeat={:?} is_trivial={}", is_repeat, is_trivial); - self.with_rib(ValueNS, ConstantItemRibKind(is_trivial), |this| { + self.with_rib(ValueNS, ConstantItemRibKind(is_trivial, item), |this| { this.with_rib( TypeNS, - ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial), + ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial, item), |this| { - this.with_label_rib(ConstantItemRibKind(is_trivial), f); + this.with_label_rib(ConstantItemRibKind(is_trivial, item), f); }, ) }); @@ -1266,6 +1282,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.with_constant_rib( IsRepeatExpr::No, true, + None, |this| { visit::walk_assoc_item( this, @@ -2200,6 +2217,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.with_constant_rib( is_repeat, constant.value.is_potential_trivial_const_param(), + None, |this| { visit::walk_anon_const(this, constant); }, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index dba30f66640..a6d0240b6fd 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -64,7 +64,7 @@ use tracing::debug; use diagnostics::{extend_span_to_previous_binding, find_span_of_binding_until_next_binding}; use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; use imports::{Import, ImportKind, ImportResolver, NameResolution}; -use late::{HasGenericParams, PathSource, Rib, RibKind::*}; +use late::{ConstantItemKind, HasGenericParams, PathSource, Rib, RibKind::*}; use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; type Res = def::Res<NodeId>; @@ -210,7 +210,7 @@ enum ResolutionError<'a> { /// Error E0434: can't capture dynamic environment in a fn item. CannotCaptureDynamicEnvironmentInFnItem, /// Error E0435: attempt to use a non-constant value in a constant. - AttemptToUseNonConstantValueInConstant, + AttemptToUseNonConstantValueInConstant(Ident, String), /// Error E0530: `X` bindings cannot shadow `Y`s. BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>), /// Error E0128: type parameters with a default cannot use forward-declared identifiers. @@ -1837,14 +1837,16 @@ impl<'a> Resolver<'a> { // Use the rib kind to determine whether we are resolving parameters // (macro 2.0 hygiene) or local variables (`macro_rules` hygiene). let rib_ident = if ribs[i].kind.contains_params() { normalized_ident } else { ident }; - if let Some(res) = ribs[i].bindings.get(&rib_ident).cloned() { + if let Some((original_rib_ident_def, res)) = ribs[i].bindings.get_key_value(&rib_ident) + { // The ident resolves to a type parameter or local variable. return Some(LexicalScopeBinding::Res(self.validate_res_from_ribs( i, rib_ident, - res, + *res, record_used, path_span, + *original_rib_ident_def, ribs, ))); } @@ -2556,6 +2558,7 @@ impl<'a> Resolver<'a> { mut res: Res, record_used: bool, span: Span, + original_rib_ident_def: Ident, all_ribs: &[Rib<'a>], ) -> Res { const CG_BUG_STR: &str = "min_const_generics resolve check didn't stop compilation"; @@ -2602,10 +2605,31 @@ impl<'a> Resolver<'a> { res_err = Some(CannotCaptureDynamicEnvironmentInFnItem); } } - ConstantItemRibKind(_) => { + ConstantItemRibKind(_, item) => { // Still doesn't deal with upvars if record_used { - self.report_error(span, AttemptToUseNonConstantValueInConstant); + let (span, resolution_error) = + if let Some((ident, constant_item_kind)) = item { + let kind_str = match constant_item_kind { + ConstantItemKind::Const => "const", + ConstantItemKind::Static => "static", + }; + let sugg = format!( + "consider using `let` instead of `{}`", + kind_str + ); + (span, AttemptToUseNonConstantValueInConstant(ident, sugg)) + } else { + let sugg = "consider using `const` instead of `let`"; + ( + rib_ident.span, + AttemptToUseNonConstantValueInConstant( + original_rib_ident_def, + sugg.to_string(), + ), + ) + }; + self.report_error(span, resolution_error); } return Res::Err; } @@ -2641,7 +2665,7 @@ impl<'a> Resolver<'a> { in_ty_param_default = true; continue; } - ConstantItemRibKind(trivial) => { + ConstantItemRibKind(trivial, _) => { let features = self.session.features_untracked(); // HACK(min_const_generics): We currently only allow `N` or `{ N }`. if !(trivial @@ -2734,7 +2758,7 @@ impl<'a> Resolver<'a> { in_ty_param_default = true; continue; } - ConstantItemRibKind(trivial) => { + ConstantItemRibKind(trivial, _) => { let features = self.session.features_untracked(); // HACK(min_const_generics): We currently only allow `N` or `{ N }`. if !(trivial diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 62859f4bef4..6074aac4032 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -819,7 +819,7 @@ pub fn default_configuration(sess: &Session) -> CrateConfig { } } ret.insert((sym::target_arch, Some(Symbol::intern(arch)))); - ret.insert((sym::target_endian, Some(Symbol::intern(end)))); + ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str())))); ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz)))); ret.insert((sym::target_env, Some(Symbol::intern(env)))); ret.insert((sym::target_vendor, Some(Symbol::intern(vendor)))); @@ -1829,11 +1829,17 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } if debugging_opts.mir_opt_level > 1 { + // Functions inlined during MIR transform can, at best, make it impossible to + // effectively cover inlined functions, and, at worst, break coverage map generation + // during LLVM codegen. For example, function counter IDs are only unique within a + // function. Inlining after these counters are injected can produce duplicate counters, + // resulting in an invalid coverage map (and ICE); so this option combination is not + // allowed. early_warn( error_format, &format!( - "`-Z mir-opt-level={}` (any level > 1) enables function inlining, which \ - limits the effectiveness of `-Z instrument-coverage`.", + "`-Z mir-opt-level={}` (or any level > 1) enables function inlining, which \ + is incompatible with `-Z instrument-coverage`. Inlining will be disabled.", debugging_opts.mir_opt_level, ), ); diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index a43080b09e9..61bfd58533a 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -4,11 +4,14 @@ pub use Primitive::*; use crate::spec::Target; use std::convert::{TryFrom, TryInto}; +use std::fmt; use std::num::NonZeroUsize; use std::ops::{Add, AddAssign, Deref, Mul, Range, RangeInclusive, Sub}; +use std::str::FromStr; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable_Generic; +use rustc_serialize::json::{Json, ToJson}; use rustc_span::Span; pub mod call; @@ -152,22 +155,19 @@ impl TargetDataLayout { } // Perform consistency checks against the Target information. - let endian_str = match dl.endian { - Endian::Little => "little", - Endian::Big => "big", - }; - if endian_str != target.endian { + if dl.endian != target.endian { return Err(format!( "inconsistent target specification: \"data-layout\" claims \ - architecture is {}-endian, while \"target-endian\" is `{}`", - endian_str, target.endian + architecture is {}-endian, while \"target-endian\" is `{}`", + dl.endian.as_str(), + target.endian.as_str(), )); } if dl.pointer_size.bits() != target.pointer_width.into() { return Err(format!( "inconsistent target specification: \"data-layout\" claims \ - pointers are {}-bit, while \"target-pointer-width\" is `{}`", + pointers are {}-bit, while \"target-pointer-width\" is `{}`", dl.pointer_size.bits(), target.pointer_width )); @@ -234,6 +234,39 @@ pub enum Endian { Big, } +impl Endian { + pub fn as_str(&self) -> &'static str { + match self { + Self::Little => "little", + Self::Big => "big", + } + } +} + +impl fmt::Debug for Endian { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.as_str()) + } +} + +impl FromStr for Endian { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "little" => Ok(Self::Little), + "big" => Ok(Self::Big), + _ => Err(format!(r#"unknown endian: "{}""#, s)), + } + } +} + +impl ToJson for Endian { + fn to_json(&self) -> Json { + self.as_str().to_json() + } +} + /// Size of a type in bytes. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)] #[derive(HashStable_Generic)] diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs index c6586b79b87..255740cb9c0 100644 --- a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs @@ -1,5 +1,6 @@ // Targets the Big endian Cortex-R4/R5 processor (ARMv7-R) +use crate::abi::Endian; use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Target, TargetOptions}; @@ -11,7 +12,7 @@ pub fn target() -> Target { arch: "arm".to_string(), options: TargetOptions { - endian: "big".to_string(), + endian: Endian::Big, linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), executables: true, linker: Some("rust-lld".to_owned()), diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs index e3d4397f612..eb82e4d17b0 100644 --- a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs @@ -1,5 +1,6 @@ // Targets the Cortex-R4F/R5F processor (ARMv7-R) +use crate::abi::Endian; use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Target, TargetOptions}; @@ -11,7 +12,7 @@ pub fn target() -> Target { arch: "arm".to_string(), options: TargetOptions { - endian: "big".to_string(), + endian: Endian::Big, linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), executables: true, linker: Some("rust-lld".to_owned()), diff --git a/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs index daa0d9da172..53398539ac2 100644 --- a/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -7,7 +8,7 @@ pub fn target() -> Target { data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), arch: "mips64".to_string(), options: TargetOptions { - endian: "big".to_string(), + endian: Endian::Big, // NOTE(mips64r2) matches C toolchain cpu: "mips64r2".to_string(), features: "+mips64r2".to_string(), diff --git a/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs index db8d0c04e6f..329fbd22721 100644 --- a/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs +++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -11,6 +12,6 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), arch: "mips64".to_string(), - options: TargetOptions { endian: "big".to_string(), mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs index a7ec1f19c9d..b41b28cbc87 100644 --- a/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -7,7 +8,7 @@ pub fn target() -> Target { data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), options: TargetOptions { - endian: "big".to_string(), + endian: Endian::Big, cpu: "mips32r2".to_string(), features: "+mips32r2,+fpxx,+nooddspreg".to_string(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs index 1ebe577bc1c..3713af43d73 100644 --- a/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/mips_unknown_linux_musl.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -11,6 +12,6 @@ pub fn target() -> Target { pointer_width: 32, data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), - options: TargetOptions { endian: "big".to_string(), mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs b/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs index 2123d5e1a0f..042ec9140fa 100644 --- a/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs +++ b/compiler/rustc_target/src/spec/mips_unknown_linux_uclibc.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -7,7 +8,7 @@ pub fn target() -> Target { data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), options: TargetOptions { - endian: "big".to_string(), + endian: Endian::Big, cpu: "mips32r2".to_string(), features: "+mips32r2,+soft-float".to_string(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs index 11b3734a105..a81c90fe0cd 100644 --- a/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/mipsisa32r6_unknown_linux_gnu.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -7,7 +8,7 @@ pub fn target() -> Target { data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), arch: "mips".to_string(), options: TargetOptions { - endian: "big".to_string(), + endian: Endian::Big, cpu: "mips32r6".to_string(), features: "+mips32r6".to_string(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs index 6282c9e1d54..3bf837fbb41 100644 --- a/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs +++ b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -7,7 +8,7 @@ pub fn target() -> Target { data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), arch: "mips64".to_string(), options: TargetOptions { - endian: "big".to_string(), + endian: Endian::Big, // NOTE(mips64r6) matches C toolchain cpu: "mips64r6".to_string(), features: "+mips64r6".to_string(), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 8d72df6850f..abc96eb3322 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -34,6 +34,7 @@ //! the target's settings, though `target-feature` and `link-args` will *add* //! to the list specified by the target, rather than replace. +use crate::abi::Endian; use crate::spec::abi::{lookup as lookup_abi, Abi}; use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; use rustc_serialize::json::{Json, ToJson}; @@ -705,8 +706,8 @@ pub struct TargetOptions { /// Whether the target is built-in or loaded from a custom target specification. pub is_builtin: bool, - /// String to use as the `target_endian` `cfg` variable. Defaults to "little". - pub endian: String, + /// Used as the `target_endian` `cfg` variable. Defaults to little endian. + pub endian: Endian, /// Width of c_int type. Defaults to "32". pub c_int_width: String, /// OS name to use for conditional compilation (`target_os`). Defaults to "none". @@ -1010,7 +1011,7 @@ impl Default for TargetOptions { fn default() -> TargetOptions { TargetOptions { is_builtin: false, - endian: "little".to_string(), + endian: Endian::Little, c_int_width: "32".to_string(), os: "none".to_string(), env: String::new(), @@ -1439,8 +1440,10 @@ impl Target { } ); } + if let Some(s) = obj.find("target-endian").and_then(Json::as_string) { + base.endian = s.parse()?; + } key!(is_builtin, bool); - key!(endian = "target-endian"); key!(c_int_width = "target-c-int-width"); key!(os); key!(env); diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs index 626865aa242..3dddeb1129c 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -11,6 +12,6 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "E-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - options: TargetOptions { endian: "big".to_string(), mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs index 03322818d33..751022c124b 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, RelroLevel, Target, TargetOptions}; pub fn target() -> Target { @@ -15,6 +16,6 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "E-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - options: TargetOptions { endian: "big".to_string(), mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs index 231539756f3..546dfbab6c7 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -11,6 +12,6 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "E-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - options: TargetOptions { endian: "big".to_string(), mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs index 1c83e3e64d4..bb55872109c 100644 --- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -11,6 +12,6 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "E-m:e-i64:64-n32:64".to_string(), arch: "powerpc64".to_string(), - options: TargetOptions { endian: "big".to_string(), ..base }, + options: TargetOptions { endian: Endian::Big, ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs index 3a9271247b0..70dd0b2aee6 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -10,6 +11,6 @@ pub fn target() -> Target { pointer_width: 32, data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - options: TargetOptions { endian: "big".to_string(), mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs index 105a0b21aaf..66118b74955 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -10,6 +11,6 @@ pub fn target() -> Target { pointer_width: 32, data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - options: TargetOptions { endian: "big".to_string(), mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs index 49d32944789..679a3a2f6aa 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -10,6 +11,6 @@ pub fn target() -> Target { pointer_width: 32, data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - options: TargetOptions { endian: "big".to_string(), mcount: "_mcount".to_string(), ..base }, + options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs index 387d6cdc456..1245098329a 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -10,10 +11,6 @@ pub fn target() -> Target { pointer_width: 32, data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - options: TargetOptions { - endian: "big".to_string(), - mcount: "__mcount".to_string(), - ..base - }, + options: TargetOptions { endian: Endian::Big, mcount: "__mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs index 20ffa07b997..bb943a8825c 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -11,10 +12,6 @@ pub fn target() -> Target { pointer_width: 32, data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), - options: TargetOptions { - endian: "big".to_string(), - features: "+secure-plt".to_string(), - ..base - }, + options: TargetOptions { endian: Endian::Big, features: "+secure-plt".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs index 0e713fccd23..4b4f118ba49 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -12,7 +13,7 @@ pub fn target() -> Target { data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(), arch: "powerpc".to_string(), options: TargetOptions { - endian: "big".to_string(), + endian: Endian::Big, // feature msync would disable instruction 'fsync' which is not supported by fsl_p1p2 features: "+secure-plt,+msync".to_string(), ..base diff --git a/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs index d6e8e6ee220..4eeea9bedfb 100644 --- a/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs @@ -1,8 +1,9 @@ +use crate::abi::Endian; use crate::spec::Target; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); - base.endian = "big".to_string(); + base.endian = Endian::Big; // z10 is the oldest CPU supported by LLVM base.cpu = "z10".to_string(); // FIXME: The data_layout string below and the ABI implementation in diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs index e9b5520ac3d..e1aa48872b9 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_linux_gnu.rs @@ -1,8 +1,9 @@ +use crate::abi::Endian; use crate::spec::Target; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); - base.endian = "big".to_string(); + base.endian = Endian::Big; base.cpu = "v9".to_string(); base.max_atomic_width = Some(64); diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs index c8e90f832d0..7d685c83100 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs @@ -1,3 +1,4 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { @@ -11,10 +12,6 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "E-m:e-i64:64-n32:64-S128".to_string(), arch: "sparc64".to_string(), - options: TargetOptions { - endian: "big".to_string(), - mcount: "__mcount".to_string(), - ..base - }, + options: TargetOptions { endian: Endian::Big, mcount: "__mcount".to_string(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs index 630ce6123f9..63b13fad4f7 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs @@ -1,8 +1,9 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); - base.endian = "big".to_string(); + base.endian = Endian::Big; base.cpu = "v9".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); diff --git a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs index aae186b2293..9e8fbff81c5 100644 --- a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs @@ -1,8 +1,9 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); - base.endian = "big".to_string(); + base.endian = Endian::Big; base.cpu = "v9".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mv8plus".to_string()); diff --git a/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs index 5f99e0b14f9..9ac56cae916 100644 --- a/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs @@ -1,8 +1,9 @@ +use crate::abi::Endian; use crate::spec::{LinkerFlavor, Target}; pub fn target() -> Target { let mut base = super::solaris_base::opts(); - base.endian = "big".to_string(); + base.endian = Endian::Big; base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); // llvm calls this "v9" base.cpu = "v9".to_string(); diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 9c60e8933d4..6154414ff60 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -103,6 +103,10 @@ pub(super) fn check_fn<'a, 'tcx>( Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(header, ..), .. }) => Some(header), + Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(header, ..), + .. + }) => Some(header), // Closures are RustCall, but they tuple their arguments, so shouldn't be checked Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => None, node => bug!("Item being checked wasn't a function/closure: {:?}", node), |
