From 515da7249e9420d9afc9b478f06ffb7f2f094954 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Mon, 1 Jul 2019 17:31:52 -0400 Subject: [PATCH 01/21] Target::arch can take more than listed options A list of options in a comment like this is almost guaranteed to become out of date. This list is missing "riscv32" and "riscv64" and perhaps other architectures as well. --- src/librustc_target/spec/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 75821aba470..3054ffabb4f 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -497,8 +497,8 @@ pub struct Target { pub target_env: String, /// Vendor name to use for conditional compilation. pub target_vendor: String, - /// Architecture to use for ABI considerations. Valid options: "x86", - /// "x86_64", "arm", "aarch64", "mips", "powerpc", and "powerpc64". + /// Architecture to use for ABI considerations. Valid options include: "x86", + /// "x86_64", "arm", "aarch64", "mips", "powerpc", "powerpc64", and others. pub arch: String, /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: String, From 7aaf0de700d1bc242d270dcc7e2fee9e3533ea0a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 4 Jul 2019 01:28:24 +0300 Subject: [PATCH 02/21] Add a test for `$crate` inside macro invocation --- .../ui/proc-macro/dollar-crate-issue-62325.rs | 24 ++++++++ .../dollar-crate-issue-62325.stderr | 4 ++ .../dollar-crate-issue-62325.stdout | 61 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 src/test/ui/proc-macro/dollar-crate-issue-62325.rs create mode 100644 src/test/ui/proc-macro/dollar-crate-issue-62325.stderr create mode 100644 src/test/ui/proc-macro/dollar-crate-issue-62325.stdout diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.rs b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs new file mode 100644 index 00000000000..8e21ca87f92 --- /dev/null +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs @@ -0,0 +1,24 @@ +//~ ERROR expected type, found `$` + +// edition:2018 +// aux-build:test-macros.rs + +// Anonymize unstable non-dummy spans while still showing dummy spans `0..0`. +// normalize-stdout-test "bytes\([^0]\w*\.\.(\w+)\)" -> "bytes(LO..$1)" +// normalize-stdout-test "bytes\((\w+)\.\.[^0]\w*\)" -> "bytes($1..HI)" + +#![feature(proc_macro_hygiene)] + +#[macro_use] +extern crate test_macros; + +type S = u8; + +macro_rules! m { () => { + #[print_attr] + struct A(identity!($crate::S)); +}} + +m!(); + +fn main() {} diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stderr b/src/test/ui/proc-macro/dollar-crate-issue-62325.stderr new file mode 100644 index 00000000000..ecc0d3853e5 --- /dev/null +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stderr @@ -0,0 +1,4 @@ +error: expected type, found `$` + +error: aborting due to previous error + diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout new file mode 100644 index 00000000000..e181a4ed54b --- /dev/null +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout @@ -0,0 +1,61 @@ +PRINT-ATTR INPUT (DISPLAY): struct A(identity!($crate :: S)); +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( identity ! ( $ crate :: S ) ) ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Ident { + ident: "struct", + span: #0 bytes(0..0), + }, + Ident { + ident: "A", + span: #0 bytes(0..0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "identity", + span: #0 bytes(0..0), + }, + Punct { + ch: '!', + spacing: Alone, + span: #0 bytes(0..0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Punct { + ch: '$', + spacing: Alone, + span: #0 bytes(0..0), + }, + Ident { + ident: "crate", + span: #0 bytes(0..0), + }, + Punct { + ch: ':', + spacing: Joint, + span: #0 bytes(0..0), + }, + Punct { + ch: ':', + spacing: Alone, + span: #0 bytes(0..0), + }, + Ident { + ident: "S", + span: #0 bytes(0..0), + }, + ], + span: #0 bytes(0..0), + }, + ], + span: #0 bytes(0..0), + }, + Punct { + ch: ';', + spacing: Alone, + span: #0 bytes(0..0), + }, +] From 4344a90308b810447adb011f3fd45fde41f7ce48 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 4 Jul 2019 02:37:34 +0300 Subject: [PATCH 03/21] Pretty-print `$crate` as `crate`/`::my_crate` in tokens ...but only if those tokens are printed from inside of AST pretty-printing. --- src/libsyntax/print/pprust.rs | 109 ++++++++++-------- .../dollar-crate-issue-57089.stdout | 4 +- src/test/ui/proc-macro/dollar-crate.stdout | 12 +- 3 files changed, 70 insertions(+), 55 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 67646cce69b..7e099bc4d50 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -18,7 +18,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree}; use rustc_target::spec::abi::{self, Abi}; use syntax_pos::{self, BytePos}; -use syntax_pos::{DUMMY_SP, FileName}; +use syntax_pos::{DUMMY_SP, FileName, Span}; use std::borrow::Cow; use std::io::Read; @@ -181,7 +181,46 @@ pub fn literal_to_string(lit: token::Lit) -> String { out } +fn ident_to_string(ident: ast::Ident, is_raw: bool) -> String { + ident_to_string_ext(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_ext( + 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() + } +} + pub fn token_kind_to_string(tok: &TokenKind) -> String { + token_kind_to_string_ext(tok, None) +} + +fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option) -> String { match *tok { token::Eq => "=".to_string(), token::Lt => "<".to_string(), @@ -227,8 +266,7 @@ pub fn token_kind_to_string(tok: &TokenKind) -> String { token::Literal(lit) => literal_to_string(lit), /* Name components */ - token::Ident(s, false) => s.to_string(), - token::Ident(s, true) => format!("r#{}", s), + token::Ident(s, is_raw) => ident_to_string_ext(s, is_raw, convert_dollar_crate), token::Lifetime(s) => s.to_string(), /* Other */ @@ -243,7 +281,12 @@ pub fn token_kind_to_string(tok: &TokenKind) -> String { } pub fn token_to_string(token: &Token) -> String { - token_kind_to_string(&token.kind) + token_to_string_ext(token, false) +} + +fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String { + let convert_dollar_crate = if convert_dollar_crate { Some(token.span) } else { None }; + token_kind_to_string_ext(&token.kind, convert_dollar_crate) } crate fn nonterminal_to_string(nt: &Nonterminal) -> String { @@ -256,9 +299,8 @@ crate 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, false) => ident_to_string(e), - token::NtIdent(e, true) => format!("r#{}", ident_to_string(e)), - token::NtLifetime(e) => ident_to_string(e), + token::NtIdent(e, is_raw) => ident_to_string(e, is_raw), + token::NtLifetime(e) => e.to_string(), token::NtLiteral(ref e) => expr_to_string(e), token::NtTT(ref tree) => tt_to_string(tree.clone()), token::NtImplItem(ref e) => impl_item_to_string(e), @@ -293,15 +335,15 @@ pub fn lifetime_to_string(lt: &ast::Lifetime) -> String { } pub fn tt_to_string(tt: tokenstream::TokenTree) -> String { - to_string(|s| s.print_tt(tt)) + to_string(|s| s.print_tt(tt, false)) } pub fn tts_to_string(tts: &[tokenstream::TokenTree]) -> String { - to_string(|s| s.print_tts(tts.iter().cloned().collect())) + tokens_to_string(tts.iter().cloned().collect()) } pub fn tokens_to_string(tokens: TokenStream) -> String { - to_string(|s| s.print_tts(tokens)) + to_string(|s| s.print_tts_ext(tokens, false)) } pub fn stmt_to_string(stmt: &ast::Stmt) -> String { @@ -344,10 +386,6 @@ pub fn path_segment_to_string(p: &ast::PathSegment) -> String { to_string(|s| s.print_path_segment(p, false)) } -pub fn ident_to_string(id: ast::Ident) -> String { - to_string(|s| s.print_ident(id)) -} - pub fn vis_to_string(v: &ast::Visibility) -> String { to_string(|s| s.print_visibility(v)) } @@ -629,11 +667,7 @@ pub trait PrintState<'a> { self.writer().word("::"); } if segment.ident.name != kw::PathRoot { - if segment.ident.name == kw::DollarCrate { - self.print_dollar_crate(segment.ident); - } else { - self.writer().word(segment.ident.as_str().to_string()); - } + self.writer().word(ident_to_string(segment.ident, segment.ident.is_raw_guess())); } } } @@ -707,10 +741,10 @@ pub trait PrintState<'a> { /// appropriate macro, transcribe back into the grammar we just parsed from, /// and then pretty-print the resulting AST nodes (so, e.g., we print /// expression arguments as expressions). It can be done! I think. - fn print_tt(&mut self, tt: tokenstream::TokenTree) { + fn print_tt(&mut self, tt: tokenstream::TokenTree, convert_dollar_crate: bool) { match tt { TokenTree::Token(ref token) => { - self.writer().word(token_to_string(&token)); + self.writer().word(token_to_string_ext(&token, convert_dollar_crate)); match token.kind { token::DocComment(..) => { self.writer().hardbreak() @@ -729,12 +763,16 @@ pub trait PrintState<'a> { } fn print_tts(&mut self, tts: tokenstream::TokenStream) { + self.print_tts_ext(tts, true) + } + + fn print_tts_ext(&mut self, tts: tokenstream::TokenStream, convert_dollar_crate: bool) { self.ibox(0); for (i, tt) in tts.into_trees().enumerate() { if i != 0 { self.writer().space(); } - self.print_tt(tt); + self.print_tt(tt, convert_dollar_crate); } self.end(); } @@ -744,21 +782,6 @@ pub trait PrintState<'a> { } fn nbsp(&mut self) { self.writer().word(" ") } - - // 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 paths 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. - fn print_dollar_crate(&mut self, ident: ast::Ident) { - let name = ident.span.ctxt().dollar_crate_name(); - if !ast::Ident::with_empty_ctxt(name).is_path_segment_keyword() { - self.writer().word("::"); - } - self.writer().word(name.as_str().to_string()) - } } impl<'a> PrintState<'a> for State<'a> { @@ -2287,11 +2310,7 @@ impl<'a> State<'a> { } crate fn print_ident(&mut self, ident: ast::Ident) { - if ident.is_raw_guess() { - self.s.word(format!("r#{}", ident)); - } else { - self.s.word(ident.as_str().to_string()); - } + self.s.word(ident_to_string(ident, ident.is_raw_guess())); self.ann.post(self, AnnNode::Ident(&ident)) } @@ -2322,11 +2341,7 @@ impl<'a> State<'a> { segment: &ast::PathSegment, colons_before_params: bool) { if segment.ident.name != kw::PathRoot { - if segment.ident.name == kw::DollarCrate { - self.print_dollar_crate(segment.ident); - } else { - self.print_ident(segment.ident); - } + self.print_ident(segment.ident); if let Some(ref args) = segment.args { self.print_generic_args(args, colons_before_params); } diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout index 0611fcb13f2..84821259d7b 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout +++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout @@ -1,4 +1,4 @@ -PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ; +PRINT-BANG INPUT (DISPLAY): struct M ( crate :: S ) ; PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -39,7 +39,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ }, ] PRINT-ATTR INPUT (DISPLAY): struct A(crate::S); -PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ; +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( crate :: S ) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", diff --git a/src/test/ui/proc-macro/dollar-crate.stdout b/src/test/ui/proc-macro/dollar-crate.stdout index 3c88ee99842..9d9677d49e3 100644 --- a/src/test/ui/proc-macro/dollar-crate.stdout +++ b/src/test/ui/proc-macro/dollar-crate.stdout @@ -1,4 +1,4 @@ -PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ; +PRINT-BANG INPUT (DISPLAY): struct M ( crate :: S ) ; PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -39,7 +39,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ }, ] PRINT-ATTR INPUT (DISPLAY): struct A(crate::S); -PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ; +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( crate :: S ) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -80,7 +80,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ }, ] PRINT-DERIVE INPUT (DISPLAY): struct D(crate::S); -PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( $crate :: S ) ; +PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( crate :: S ) ; PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -120,7 +120,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ span: #2 bytes(LO..HI), }, ] -PRINT-BANG INPUT (DISPLAY): struct M ( $crate :: S ) ; +PRINT-BANG INPUT (DISPLAY): struct M ( ::dollar_crate_external :: S ) ; PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -161,7 +161,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ }, ] PRINT-ATTR INPUT (DISPLAY): struct A(::dollar_crate_external::S); -PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( $crate :: S ) ; +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( ::dollar_crate_external :: S ) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -202,7 +202,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ }, ] PRINT-DERIVE INPUT (DISPLAY): struct D(::dollar_crate_external::S); -PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( $crate :: S ) ; +PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ( ::dollar_crate_external :: S ) ; PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "struct", From 39975077868fc63a7e9a3cec5130adb3607f6838 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 5 Jul 2019 03:09:24 +0300 Subject: [PATCH 04/21] Resolve `$crate` in all hygienic contexts for pretty-pringing Stop visiting AST to discover those contexts, just iterate through hygiene data instead --- src/librustc_resolve/build_reduced_graph.rs | 5 ++- src/librustc_resolve/macros.rs | 27 +++++---------- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax_pos/hygiene.rs | 30 ++++++++++------- .../ui/proc-macro/dollar-crate-issue-62325.rs | 3 +- .../dollar-crate-issue-62325.stderr | 4 --- .../dollar-crate-issue-62325.stdout | 33 ++++++++----------- 8 files changed, 47 insertions(+), 59 deletions(-) delete mode 100644 src/test/ui/proc-macro/dollar-crate-issue-62325.stderr diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 3921bd30df2..49116f3f171 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -758,7 +758,10 @@ impl<'a> Resolver<'a> { } pub fn macro_def_scope(&mut self, expansion: Mark) -> Module<'a> { - let def_id = self.macro_defs[&expansion]; + let def_id = match self.macro_defs.get(&expansion) { + Some(def_id) => *def_id, + None => return self.graph_root, + }; if let Some(id) = self.definitions.as_local_node_id(def_id) { self.local_macro_def_scopes[&id] } else if def_id.krate == CrateNum::BuiltinMacros { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index f26c3b8ae6a..8f23c9813f7 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -17,12 +17,11 @@ use syntax::errors::DiagnosticBuilder; use syntax::ext::base::{self, Determinacy}; use syntax::ext::base::{MacroKind, SyntaxExtension}; use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; -use syntax::ext::hygiene::Mark; +use syntax::ext::hygiene::{self, Mark}; use syntax::ext::tt::macro_rules; use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name}; use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES}; use syntax::symbol::{Symbol, kw, sym}; -use syntax::visit::Visitor; use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::{Span, DUMMY_SP}; use errors::Applicability; @@ -146,24 +145,14 @@ impl<'a> base::Resolver for Resolver<'a> { mark } - fn resolve_dollar_crates(&mut self, fragment: &AstFragment) { - struct ResolveDollarCrates<'a, 'b> { - resolver: &'a mut Resolver<'b> - } - impl<'a> Visitor<'a> for ResolveDollarCrates<'a, '_> { - fn visit_ident(&mut self, ident: Ident) { - if ident.name == kw::DollarCrate { - let name = match self.resolver.resolve_crate_root(ident).kind { - ModuleKind::Def(.., name) if name != kw::Invalid => name, - _ => kw::Crate, - }; - ident.span.ctxt().set_dollar_crate_name(name); - } + fn resolve_dollar_crates(&mut self) { + hygiene::update_dollar_crate_names(|ctxt| { + let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt)); + match self.resolve_crate_root(ident).kind { + ModuleKind::Def(.., name) if name != kw::Invalid => name, + _ => kw::Crate, } - fn visit_mac(&mut self, _: &ast::Mac) {} - } - - fragment.visit_with(&mut ResolveDollarCrates { resolver: self }); + }); } fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 15c0b6ca5aa..c0ba41b8af4 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -701,7 +701,7 @@ pub trait Resolver { fn get_module_scope(&mut self, id: ast::NodeId) -> Mark; - fn resolve_dollar_crates(&mut self, fragment: &AstFragment); + fn resolve_dollar_crates(&mut self); fn visit_ast_fragment_with_placeholders(&mut self, mark: Mark, fragment: &AstFragment, derives: &[Mark]); fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 74ef5cbe917..053686b8b1f 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -429,7 +429,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { fn collect_invocations(&mut self, mut fragment: AstFragment, derives: &[Mark]) -> (AstFragment, Vec) { // Resolve `$crate`s in the fragment for pretty-printing. - self.cx.resolver.resolve_dollar_crates(&fragment); + self.cx.resolver.resolve_dollar_crates(); let invocations = { let mut collector = InvocationCollector { diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index a6c8c76cf23..f52952ca402 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -33,7 +33,7 @@ use crate::symbol::{kw, Symbol}; use serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; -use std::{fmt, mem}; +use std::fmt; /// A SyntaxContext represents a chain of macro expansions (represented by marks). #[derive(Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord, Hash)] @@ -387,6 +387,23 @@ pub fn walk_chain(span: Span, to: SyntaxContext) -> Span { HygieneData::with(|data| data.walk_chain(span, to)) } +pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symbol) { + // The new contexts that need updating are at the end of the list and have `$crate` as a name. + let (len, to_update) = HygieneData::with(|data| ( + data.syntax_contexts.len(), + data.syntax_contexts.iter().rev() + .take_while(|scdata| scdata.dollar_crate_name == kw::DollarCrate).count() + )); + // The callback must be called from outside of the `HygieneData` lock, + // since it will try to acquire it too. + let range_to_update = len - to_update .. len; + let names: Vec<_> = + range_to_update.clone().map(|idx| get_name(SyntaxContext::from_u32(idx as u32))).collect(); + HygieneData::with(|data| range_to_update.zip(names.into_iter()).for_each(|(idx, name)| { + data.syntax_contexts[idx].dollar_crate_name = name; + })) +} + impl SyntaxContext { #[inline] pub const fn empty() -> Self { @@ -614,17 +631,6 @@ impl SyntaxContext { pub fn dollar_crate_name(self) -> Symbol { HygieneData::with(|data| data.syntax_contexts[self.0 as usize].dollar_crate_name) } - - pub fn set_dollar_crate_name(self, dollar_crate_name: Symbol) { - HygieneData::with(|data| { - let prev_dollar_crate_name = mem::replace( - &mut data.syntax_contexts[self.0 as usize].dollar_crate_name, dollar_crate_name - ); - assert!(dollar_crate_name == prev_dollar_crate_name || - prev_dollar_crate_name == kw::DollarCrate, - "$crate name is reset for a syntax context"); - }) - } } impl fmt::Debug for SyntaxContext { diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.rs b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs index 8e21ca87f92..35c61b2bc69 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-62325.rs +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs @@ -1,5 +1,4 @@ -//~ ERROR expected type, found `$` - +// check-pass // edition:2018 // aux-build:test-macros.rs diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stderr b/src/test/ui/proc-macro/dollar-crate-issue-62325.stderr deleted file mode 100644 index ecc0d3853e5..00000000000 --- a/src/test/ui/proc-macro/dollar-crate-issue-62325.stderr +++ /dev/null @@ -1,4 +0,0 @@ -error: expected type, found `$` - -error: aborting due to previous error - diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout index e181a4ed54b..033699d8d86 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout @@ -1,61 +1,56 @@ -PRINT-ATTR INPUT (DISPLAY): struct A(identity!($crate :: S)); -PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( identity ! ( $ crate :: S ) ) ; +PRINT-ATTR INPUT (DISPLAY): struct A(identity!(crate :: S)); +PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ( identity ! ( crate :: S ) ) ; PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, Ident { ident: "A", - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "identity", - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, Punct { ch: '!', spacing: Alone, - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, Group { delimiter: Parenthesis, stream: TokenStream [ - Punct { - ch: '$', - spacing: Alone, - span: #0 bytes(0..0), - }, Ident { - ident: "crate", - span: #0 bytes(0..0), + ident: "$crate", + span: #2 bytes(LO..HI), }, Punct { ch: ':', spacing: Joint, - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, Punct { ch: ':', spacing: Alone, - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, Ident { ident: "S", - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, ], - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, ], - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, Punct { ch: ';', spacing: Alone, - span: #0 bytes(0..0), + span: #2 bytes(LO..HI), }, ] From 60f1449b61a2e118916105d5fc225c005757e42e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 1 Jul 2019 11:49:44 -0700 Subject: [PATCH 05/21] Add Iterator::partition_mut() and is_partitioned() `partition_mut()` swaps `&mut T` items in-place to satisfy the predicate, so all `true` items precede all `false` items. This requires a `DoubleEndedIterator` so we can search from front and back for items that need swapping. `is_partitioned()` checks whether the predicate is already satisfied. --- src/libcore/iter/traits/iterator.rs | 71 +++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index b9a98236f18..b5835f19d74 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1472,6 +1472,11 @@ pub trait Iterator { /// `partition()` returns a pair, all of the elements for which it returned /// `true`, and all of the elements for which it returned `false`. /// + /// See also [`is_partitioned()`] and [`partition_mut()`]. + /// + /// [`is_partitioned()`]: #method.is_partitioned + /// [`partition_mut()`]: #method.partition_mut + /// /// # Examples /// /// Basic usage: @@ -1506,6 +1511,72 @@ pub trait Iterator { (left, right) } + /// Reorder the elements of this iterator *in-place* according to the given predicate, + /// such that all those that return `true` precede all those that return `false`. + /// + /// The relative order of partitioned items is not maintained. + /// + /// See also [`is_partitioned()`] and [`partition()`]. + /// + /// [`is_partitioned()`]: #method.is_partitioned + /// [`partition()`]: #method.partition + /// + /// # Examples + /// + /// ``` + /// #![feature(iter_partition_mut)] + /// + /// let mut a = [1, 2, 3, 4, 5, 6, 7]; + /// + /// // partition in-place between evens and odds + /// a.iter_mut().partition_mut(|&n| n % 2 == 0); + /// + /// assert!(a[..3].iter().all(|&n| n % 2 == 0)); // evens + /// assert!(a[3..].iter().all(|&n| n % 2 == 1)); // odds + /// ``` + #[unstable(feature = "iter_partition_mut", reason = "new API", issue = "0")] + fn partition_mut<'a, T: 'a, P>(mut self, mut predicate: P) + where + Self: Sized + DoubleEndedIterator, + P: FnMut(&T) -> bool, + { + // Repeatedly find the first `false` and swap it with the last `true`. + while let Some(head) = self.find(|x| !predicate(x)) { + if let Some(tail) = self.rfind(|x| predicate(x)) { + crate::mem::swap(head, tail); + } else { + break; + } + } + } + + /// Checks if the elements of this iterator are partitioned according to the given predicate, + /// such that all those that return `true` precede all those that return `false`. + /// + /// See also [`partition()`] and [`partition_mut()`]. + /// + /// [`partition()`]: #method.partition + /// [`partition_mut()`]: #method.partition_mut + /// + /// # Examples + /// + /// ``` + /// #![feature(iter_is_partitioned)] + /// + /// assert!("Iterator".chars().is_partitioned(char::is_uppercase)); + /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase)); + /// ``` + #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "0")] + fn is_partitioned

(mut self, mut predicate: P) -> bool + where + Self: Sized, + P: FnMut(Self::Item) -> bool, + { + // Either all items test `true`, or the first clause stops at `false` + // and we check that there are no more `true` items after that. + self.all(&mut predicate) || !self.any(predicate) + } + /// An iterator method that applies a function as long as it returns /// successfully, producing a single, final value. /// From cdeec0a618248b9321aed338b09c94a53338626e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 1 Jul 2019 15:17:39 -0700 Subject: [PATCH 06/21] Capitalize example comment Co-Authored-By: Mazdak Farrokhzad --- src/libcore/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index b5835f19d74..e06030aee6b 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1528,7 +1528,7 @@ pub trait Iterator { /// /// let mut a = [1, 2, 3, 4, 5, 6, 7]; /// - /// // partition in-place between evens and odds + /// // Partition in-place between evens and odds /// a.iter_mut().partition_mut(|&n| n % 2 == 0); /// /// assert!(a[..3].iter().all(|&n| n % 2 == 0)); // evens From cd0ebc43c7f0238d09bdf722409e8d77a41a37db Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 1 Jul 2019 15:34:53 -0700 Subject: [PATCH 07/21] Rename partition_mut to partition_in_place --- src/libcore/iter/traits/iterator.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index e06030aee6b..45aafb4bd7f 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1472,10 +1472,10 @@ pub trait Iterator { /// `partition()` returns a pair, all of the elements for which it returned /// `true`, and all of the elements for which it returned `false`. /// - /// See also [`is_partitioned()`] and [`partition_mut()`]. + /// See also [`is_partitioned()`] and [`partition_in_place()`]. /// /// [`is_partitioned()`]: #method.is_partitioned - /// [`partition_mut()`]: #method.partition_mut + /// [`partition_in_place()`]: #method.partition_in_place /// /// # Examples /// @@ -1524,18 +1524,18 @@ pub trait Iterator { /// # Examples /// /// ``` - /// #![feature(iter_partition_mut)] + /// #![feature(iter_partition_in_place)] /// /// let mut a = [1, 2, 3, 4, 5, 6, 7]; /// /// // Partition in-place between evens and odds - /// a.iter_mut().partition_mut(|&n| n % 2 == 0); + /// a.iter_mut().partition_in_place(|&n| n % 2 == 0); /// /// assert!(a[..3].iter().all(|&n| n % 2 == 0)); // evens /// assert!(a[3..].iter().all(|&n| n % 2 == 1)); // odds /// ``` - #[unstable(feature = "iter_partition_mut", reason = "new API", issue = "0")] - fn partition_mut<'a, T: 'a, P>(mut self, mut predicate: P) + #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "0")] + fn partition_in_place<'a, T: 'a, P>(mut self, mut predicate: P) where Self: Sized + DoubleEndedIterator, P: FnMut(&T) -> bool, @@ -1553,10 +1553,10 @@ pub trait Iterator { /// Checks if the elements of this iterator are partitioned according to the given predicate, /// such that all those that return `true` precede all those that return `false`. /// - /// See also [`partition()`] and [`partition_mut()`]. + /// See also [`partition()`] and [`partition_in_place()`]. /// /// [`partition()`]: #method.partition - /// [`partition_mut()`]: #method.partition_mut + /// [`partition_in_place()`]: #method.partition_in_place /// /// # Examples /// From 0492f972c7751daaa819a937c75ceadd0cf5326e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 8 Jul 2019 18:25:19 -0700 Subject: [PATCH 08/21] Return the true count from partition_in_place --- src/libcore/iter/traits/iterator.rs | 41 ++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 45aafb4bd7f..b123d4a1469 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1513,6 +1513,7 @@ pub trait Iterator { /// Reorder the elements of this iterator *in-place* according to the given predicate, /// such that all those that return `true` precede all those that return `false`. + /// Returns the number of `true` elements found. /// /// The relative order of partitioned items is not maintained. /// @@ -1529,25 +1530,53 @@ pub trait Iterator { /// let mut a = [1, 2, 3, 4, 5, 6, 7]; /// /// // Partition in-place between evens and odds - /// a.iter_mut().partition_in_place(|&n| n % 2 == 0); + /// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0); /// - /// assert!(a[..3].iter().all(|&n| n % 2 == 0)); // evens - /// assert!(a[3..].iter().all(|&n| n % 2 == 1)); // odds + /// assert_eq!(i, 3); + /// assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens + /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds /// ``` #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "0")] - fn partition_in_place<'a, T: 'a, P>(mut self, mut predicate: P) + fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize where Self: Sized + DoubleEndedIterator, P: FnMut(&T) -> bool, { + // FIXME: should we worry about the count overflowing? The only way to have more than + // `usize::MAX` mutable references is with ZSTs, which aren't useful to partition... + + // These closure "factory" functions exist to avoid genericity in `Self`. + + #[inline] + fn is_false<'a, T>( + predicate: &'a mut impl FnMut(&T) -> bool, + true_count: &'a mut usize, + ) -> impl FnMut(&&mut T) -> bool + 'a { + move |x| { + let p = predicate(&**x); + *true_count += p as usize; + !p + } + } + + #[inline] + fn is_true( + predicate: &mut impl FnMut(&T) -> bool + ) -> impl FnMut(&&mut T) -> bool + '_ { + move |x| predicate(&**x) + } + // Repeatedly find the first `false` and swap it with the last `true`. - while let Some(head) = self.find(|x| !predicate(x)) { - if let Some(tail) = self.rfind(|x| predicate(x)) { + let mut true_count = 0; + while let Some(head) = self.find(is_false(predicate, &mut true_count)) { + if let Some(tail) = self.rfind(is_true(predicate)) { crate::mem::swap(head, tail); + true_count += 1; } else { break; } } + true_count } /// Checks if the elements of this iterator are partitioned according to the given predicate, From 265e3a6230364455dfe55378b59833be93e17084 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 9 Jul 2019 12:39:19 -0700 Subject: [PATCH 09/21] Unit test Iterator::partition_in_place and is_partitioned --- src/libcore/tests/iter.rs | 36 ++++++++++++++++++++++++++++++++++++ src/libcore/tests/lib.rs | 2 ++ 2 files changed, 38 insertions(+) diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 4d840ef24c8..b7b0849e212 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -2460,3 +2460,39 @@ fn test_is_sorted() { assert!(!["c", "bb", "aaa"].iter().is_sorted()); assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len())); } + +#[test] +fn test_partition() { + fn check(xs: &mut [i32], ref p: impl Fn(&i32) -> bool, expected: usize) { + let i = xs.iter_mut().partition_in_place(p); + assert_eq!(expected, i); + assert!(xs[..i].iter().all(p)); + assert!(!xs[i..].iter().any(p)); + assert!(xs.iter().is_partitioned(p)); + if i == 0 || i == xs.len() { + assert!(xs.iter().rev().is_partitioned(p)); + } else { + assert!(!xs.iter().rev().is_partitioned(p)); + } + } + + check(&mut [], |_| true, 0); + check(&mut [], |_| false, 0); + + check(&mut [0], |_| true, 1); + check(&mut [0], |_| false, 0); + + check(&mut [-1, 1], |&x| x > 0, 1); + check(&mut [-1, 1], |&x| x < 0, 1); + + let ref mut xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + check(xs, |_| true, 10); + check(xs, |_| false, 0); + check(xs, |&x| x % 2 == 0, 5); // evens + check(xs, |&x| x % 2 == 1, 5); // odds + check(xs, |&x| x % 3 == 0, 4); // multiple of 3 + check(xs, |&x| x % 4 == 0, 3); // multiple of 4 + check(xs, |&x| x % 5 == 0, 2); // multiple of 5 + check(xs, |&x| x < 3, 3); // small + check(xs, |&x| x > 6, 3); // large +} diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 4b48d122590..cbb6423d710 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -31,6 +31,8 @@ #![feature(slice_partition_dedup)] #![feature(int_error_matching)] #![feature(const_fn)] +#![feature(iter_partition_in_place)] +#![feature(iter_is_partitioned)] #![warn(rust_2018_idioms)] extern crate test; From 4cb67c0f1c429a1a1e2ec8c3e02714557feeb60d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 9 Jul 2019 22:21:55 +0300 Subject: [PATCH 10/21] Add a test case with `$crate` from other crate --- .../auxiliary/dollar-crate-external.rs | 6 ++ .../ui/proc-macro/dollar-crate-issue-62325.rs | 4 ++ .../dollar-crate-issue-62325.stdout | 56 +++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs b/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs index d5d393b5a64..bdcdb7922ca 100644 --- a/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs +++ b/src/test/ui/proc-macro/auxiliary/dollar-crate-external.rs @@ -14,3 +14,9 @@ macro_rules! external { struct D($crate::S); }; } + +#[macro_export] +macro_rules! issue_62325 { () => { + #[print_attr] + struct B(identity!($crate::S)); +}} diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.rs b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs index 35c61b2bc69..b7b152e6692 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-62325.rs +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs @@ -1,6 +1,7 @@ // check-pass // edition:2018 // aux-build:test-macros.rs +// aux-build:dollar-crate-external.rs // Anonymize unstable non-dummy spans while still showing dummy spans `0..0`. // normalize-stdout-test "bytes\([^0]\w*\.\.(\w+)\)" -> "bytes(LO..$1)" @@ -10,6 +11,7 @@ #[macro_use] extern crate test_macros; +extern crate dollar_crate_external; type S = u8; @@ -20,4 +22,6 @@ macro_rules! m { () => { m!(); +dollar_crate_external::issue_62325!(); + fn main() {} diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout index 033699d8d86..17ad1a7af70 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout @@ -54,3 +54,59 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ span: #2 bytes(LO..HI), }, ] +PRINT-ATTR INPUT (DISPLAY): struct B(identity!(::dollar_crate_external :: S)); +PRINT-ATTR RE-COLLECTED (DISPLAY): struct B ( identity ! ( ::dollar_crate_external :: S ) ) ; +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Ident { + ident: "struct", + span: #7 bytes(LO..HI), + }, + Ident { + ident: "B", + span: #7 bytes(LO..HI), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "identity", + span: #7 bytes(LO..HI), + }, + Punct { + ch: '!', + spacing: Alone, + span: #7 bytes(LO..HI), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "$crate", + span: #7 bytes(LO..HI), + }, + Punct { + ch: ':', + spacing: Joint, + span: #7 bytes(LO..HI), + }, + Punct { + ch: ':', + spacing: Alone, + span: #7 bytes(LO..HI), + }, + Ident { + ident: "S", + span: #7 bytes(LO..HI), + }, + ], + span: #7 bytes(LO..HI), + }, + ], + span: #7 bytes(LO..HI), + }, + Punct { + ch: ';', + spacing: Alone, + span: #7 bytes(LO..HI), + }, +] From 04304fcd16e40c936dc5ba71c9ac3c445597f8bb Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 6 Jul 2019 19:02:48 +0200 Subject: [PATCH 11/21] Pass GUIDPreservedSymbols to thinLTOResolvePrevailingInIndex() --- src/rustllvm/PassWrapper.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 0ebef82d376..cea88f14dcc 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -913,7 +913,10 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, GlobalValue::LinkageTypes NewLinkage) { ResolvedODR[ModuleIdentifier][GUID] = NewLinkage; }; -#if LLVM_VERSION_GE(8, 0) +#if LLVM_VERSION_GE(9, 0) + thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage, + Ret->GUIDPreservedSymbols); +#elif LLVM_VERSION_GE(8, 0) thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage); #else thinLTOResolveWeakForLinkerInIndex(Ret->Index, isPrevailing, recordNewLinkage); From eb338220911fbcf0661e4f8802b23d0bd4e5d077 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 6 Jul 2019 21:52:25 +0200 Subject: [PATCH 12/21] Pass type to byval attributes --- src/librustc_codegen_llvm/abi.rs | 64 +++++++++++++++------------ src/librustc_codegen_llvm/declare.rs | 2 +- src/librustc_codegen_llvm/llvm/ffi.rs | 2 + src/rustllvm/RustWrapper.cpp | 22 +++++++++ 4 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 38d4b7e3f9d..ff87afe0c44 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -34,17 +34,17 @@ trait ArgAttributeExt { impl ArgAttributeExt for ArgAttribute { fn for_each_kind(&self, mut f: F) where F: FnMut(llvm::Attribute) { for_each_kind!(self, f, - ByVal, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg) + NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg) } } pub trait ArgAttributesExt { - fn apply_llfn(&self, idx: AttributePlace, llfn: &Value); - fn apply_callsite(&self, idx: AttributePlace, callsite: &Value); + fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>); + fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>); } impl ArgAttributesExt for ArgAttributes { - fn apply_llfn(&self, idx: AttributePlace, llfn: &Value) { + fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>) { let mut regular = self.regular; unsafe { let deref = self.pointee_size.bytes(); @@ -65,11 +65,14 @@ impl ArgAttributesExt for ArgAttributes { idx.as_uint(), align.bytes() as u32); } + if regular.contains(ArgAttribute::ByVal) { + llvm::LLVMRustAddByValAttr(llfn, idx.as_uint(), ty.unwrap()); + } regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn)); } } - fn apply_callsite(&self, idx: AttributePlace, callsite: &Value) { + fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>) { let mut regular = self.regular; unsafe { let deref = self.pointee_size.bytes(); @@ -90,6 +93,9 @@ impl ArgAttributesExt for ArgAttributes { idx.as_uint(), align.bytes() as u32); } + if regular.contains(ArgAttribute::ByVal) { + llvm::LLVMRustAddByValCallSiteAttr(callsite, idx.as_uint(), ty.unwrap()); + } regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite)); } } @@ -298,7 +304,7 @@ pub trait FnTypeLlvmExt<'tcx> { fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type; fn llvm_cconv(&self) -> llvm::CallConv; - fn apply_attrs_llfn(&self, llfn: &'ll Value); + fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value); fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value); } @@ -384,51 +390,51 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { } } - fn apply_attrs_llfn(&self, llfn: &'ll Value) { + fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) { let mut i = 0; - let mut apply = |attrs: &ArgAttributes| { - attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn); + let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| { + attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn, ty); i += 1; }; match self.ret.mode { PassMode::Direct(ref attrs) => { - attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn); + attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn, None); } - PassMode::Indirect(ref attrs, _) => apply(attrs), + PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(cx))), _ => {} } for arg in &self.args { if arg.pad.is_some() { - apply(&ArgAttributes::new()); + apply(&ArgAttributes::new(), None); } match arg.mode { PassMode::Ignore(_) => {} PassMode::Direct(ref attrs) | - PassMode::Indirect(ref attrs, None) => apply(attrs), + PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(cx))), PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => { - apply(attrs); - apply(extra_attrs); + apply(attrs, None); + apply(extra_attrs, None); } PassMode::Pair(ref a, ref b) => { - apply(a); - apply(b); + apply(a, None); + apply(b, None); } - PassMode::Cast(_) => apply(&ArgAttributes::new()), + PassMode::Cast(_) => apply(&ArgAttributes::new(), None), } } } fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) { let mut i = 0; - let mut apply = |attrs: &ArgAttributes| { - attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite); + let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| { + attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite, ty); i += 1; }; match self.ret.mode { PassMode::Direct(ref attrs) => { - attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite); + attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite, None); } - PassMode::Indirect(ref attrs, _) => apply(attrs), + PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(bx))), _ => {} } if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi { @@ -446,21 +452,21 @@ impl<'tcx> FnTypeLlvmExt<'tcx> for FnType<'tcx, Ty<'tcx>> { } for arg in &self.args { if arg.pad.is_some() { - apply(&ArgAttributes::new()); + apply(&ArgAttributes::new(), None); } match arg.mode { PassMode::Ignore(_) => {} PassMode::Direct(ref attrs) | - PassMode::Indirect(ref attrs, None) => apply(attrs), + PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(bx))), PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => { - apply(attrs); - apply(extra_attrs); + apply(attrs, None); + apply(extra_attrs, None); } PassMode::Pair(ref a, ref b) => { - apply(a); - apply(b); + apply(a, None); + apply(b, None); } - PassMode::Cast(_) => apply(&ArgAttributes::new()), + PassMode::Cast(_) => apply(&ArgAttributes::new(), None), } } diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index bcb14b8899e..62eab0f3d4e 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -107,7 +107,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { llvm::Attribute::NoReturn.apply_llfn(Function, llfn); } - fty.apply_attrs_llfn(llfn); + fty.apply_attrs_llfn(self, llfn); llfn } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index a5c295cd452..75f639ec3ec 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -794,6 +794,7 @@ extern "C" { pub fn LLVMRustAddAlignmentAttr(Fn: &Value, index: c_uint, bytes: u32); pub fn LLVMRustAddDereferenceableAttr(Fn: &Value, index: c_uint, bytes: u64); pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: &Value, index: c_uint, bytes: u64); + pub fn LLVMRustAddByValAttr(Fn: &Value, index: c_uint, ty: &Type); pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute); pub fn LLVMRustAddFunctionAttrStringValue(Fn: &Value, index: c_uint, @@ -824,6 +825,7 @@ extern "C" { pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64); + pub fn LLVMRustAddByValCallSiteAttr(Instr: &Value, index: c_uint, ty: &Type); // Operations on load/store instructions (only) pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 66453c08a66..16d08ee534e 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -237,6 +237,17 @@ extern "C" void LLVMRustAddDereferenceableOrNullCallSiteAttr(LLVMValueRef Instr, Call->getContext(), Index, B)); } +extern "C" void LLVMRustAddByValCallSiteAttr(LLVMValueRef Instr, unsigned Index, + LLVMTypeRef Ty) { + CallSite Call = CallSite(unwrap(Instr)); +#if LLVM_VERSION_GE(9, 0) + Attribute Attr = Attribute::getWithByValType(Call->getContext(), unwrap(Ty)); +#else + Attribute Attr = Attribute::get(Call->getContext(), Attribute::ByVal); +#endif + Call.addAttribute(Index, Attr); +} + extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index, LLVMRustAttribute RustAttr) { Function *A = unwrap(Fn); @@ -271,6 +282,17 @@ extern "C" void LLVMRustAddDereferenceableOrNullAttr(LLVMValueRef Fn, A->addAttributes(Index, B); } +extern "C" void LLVMRustAddByValAttr(LLVMValueRef Fn, unsigned Index, + LLVMTypeRef Ty) { + Function *F = unwrap(Fn); +#if LLVM_VERSION_GE(9, 0) + Attribute Attr = Attribute::getWithByValType(F->getContext(), unwrap(Ty)); +#else + Attribute Attr = Attribute::get(F->getContext(), Attribute::ByVal); +#endif + F->addAttribute(Index, Attr); +} + extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn, unsigned Index, const char *Name, From b57c499ea227a973fc3eb319cbe6d5019948d86c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 7 Jul 2019 17:44:00 +0200 Subject: [PATCH 13/21] Translate target features for LLVM 9 --- src/librustc_codegen_llvm/attributes.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 94abf1796d3..33b50401b22 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -119,6 +119,29 @@ pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { const_cstr!("probe-stack"), const_cstr!("__rust_probestack")); } +fn translate_obsolete_target_features(feature: &str) -> &str { + const LLVM9_FEATURE_CHANGES: &[(&str, &str)] = &[ + ("+fp-only-sp", "-fp64"), + ("-fp-only-sp", "+fp64"), + ("+d16", "-d32"), + ("-d16", "+d32"), + ]; + if llvm_util::get_major_version() >= 9 { + for &(old, new) in LLVM9_FEATURE_CHANGES { + if feature == old { + return new; + } + } + } else { + for &(old, new) in LLVM9_FEATURE_CHANGES { + if feature == new { + return old; + } + } + } + feature +} + pub fn llvm_target_features(sess: &Session) -> impl Iterator { const RUSTC_SPECIFIC_FEATURES: &[&str] = &[ "crt-static", @@ -129,6 +152,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator { sess.target.target.options.features.split(',') .chain(cmdline) .filter(|l| !l.is_empty()) + .map(translate_obsolete_target_features) } pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { From 3170b62cca5693d355e702a26777679316647b20 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 7 Jul 2019 18:10:12 +0200 Subject: [PATCH 14/21] Use new feature names in target feature lists --- src/librustc_target/spec/armebv7r_none_eabihf.rs | 2 +- src/librustc_target/spec/armv7_linux_androideabi.rs | 2 +- src/librustc_target/spec/armv7_unknown_freebsd.rs | 2 +- src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs | 2 +- .../spec/armv7_unknown_linux_musleabihf.rs | 2 +- src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs | 2 +- src/librustc_target/spec/armv7r_none_eabihf.rs | 2 +- src/librustc_target/spec/thumbv7em_none_eabihf.rs | 8 ++++---- src/librustc_target/spec/thumbv8m_main_none_eabihf.rs | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/librustc_target/spec/armebv7r_none_eabihf.rs b/src/librustc_target/spec/armebv7r_none_eabihf.rs index 50ee76414ef..ff8e43100e2 100644 --- a/src/librustc_target/spec/armebv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armebv7r_none_eabihf.rs @@ -21,7 +21,7 @@ pub fn target() -> TargetResult { linker: Some("rust-lld".to_owned()), relocation_model: "static".to_string(), panic_strategy: PanicStrategy::Abort, - features: "+vfp3,+d16,+fp-only-sp".to_string(), + features: "+vfp3,-d32,-fp16".to_string(), max_atomic_width: Some(32), abi_blacklist: super::arm_base::abi_blacklist(), emit_debug_gdb_scripts: false, diff --git a/src/librustc_target/spec/armv7_linux_androideabi.rs b/src/librustc_target/spec/armv7_linux_androideabi.rs index 92f1a55e024..4c13c6669c3 100644 --- a/src/librustc_target/spec/armv7_linux_androideabi.rs +++ b/src/librustc_target/spec/armv7_linux_androideabi.rs @@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::android_base::opts(); - base.features = "+v7,+thumb-mode,+thumb2,+vfp3,+d16,-neon".to_string(); + base.features = "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".to_string(); base.max_atomic_width = Some(64); base.pre_link_args .get_mut(&LinkerFlavor::Gcc).unwrap().push("-march=armv7-a".to_string()); diff --git a/src/librustc_target/spec/armv7_unknown_freebsd.rs b/src/librustc_target/spec/armv7_unknown_freebsd.rs index ca7ab474bef..0509ddab048 100644 --- a/src/librustc_target/spec/armv7_unknown_freebsd.rs +++ b/src/librustc_target/spec/armv7_unknown_freebsd.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(), + features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(), max_atomic_width: Some(64), abi_blacklist: super::arm_base::abi_blacklist(), target_mcount: "\u{1}__gnu_mcount_nc".to_string(), diff --git a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs index f0952cccb20..ff34fda7502 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs @@ -19,7 +19,7 @@ pub fn target() -> TargetResult { options: TargetOptions { // Info about features at https://wiki.debian.org/ArmHardFloatPort - features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(), + features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(), cpu: "generic".to_string(), max_atomic_width: Some(64), abi_blacklist: super::arm_base::abi_blacklist(), diff --git a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs index a9974f6b80c..de22fbbaa4c 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs @@ -22,7 +22,7 @@ pub fn target() -> TargetResult { // Most of these settings are copied from the armv7_unknown_linux_gnueabihf // target. options: TargetOptions { - features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(), + features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(), cpu: "generic".to_string(), max_atomic_width: Some(64), abi_blacklist: super::arm_base::abi_blacklist(), diff --git a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs index e2d55e9317b..a654e40d0ae 100644 --- a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(), + features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(), cpu: "generic".to_string(), max_atomic_width: Some(64), abi_blacklist: super::arm_base::abi_blacklist(), diff --git a/src/librustc_target/spec/armv7r_none_eabihf.rs b/src/librustc_target/spec/armv7r_none_eabihf.rs index 06ef9f3ec4e..24772475e04 100644 --- a/src/librustc_target/spec/armv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armv7r_none_eabihf.rs @@ -21,7 +21,7 @@ pub fn target() -> TargetResult { linker: Some("rust-lld".to_owned()), relocation_model: "static".to_string(), panic_strategy: PanicStrategy::Abort, - features: "+vfp3,+d16,+fp-only-sp".to_string(), + features: "+vfp3,-d32,-fp16".to_string(), max_atomic_width: Some(32), abi_blacklist: super::arm_base::abi_blacklist(), emit_debug_gdb_scripts: false, diff --git a/src/librustc_target/spec/thumbv7em_none_eabihf.rs b/src/librustc_target/spec/thumbv7em_none_eabihf.rs index e4358bdd799..5c386a00ba4 100644 --- a/src/librustc_target/spec/thumbv7em_none_eabihf.rs +++ b/src/librustc_target/spec/thumbv7em_none_eabihf.rs @@ -6,7 +6,7 @@ // Additionally, this target uses the "hard" floating convention (ABI) where floating point values // are passed to/from subroutines via FPU registers (S0, S1, D0, D1, etc.). // -// To opt into double precision hardware support, use the `-C target-feature=-fp-only-sp` flag. +// To opt into double precision hardware support, use the `-C target-feature=+fp64` flag. use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult}; @@ -26,14 +26,14 @@ pub fn target() -> TargetResult { options: TargetOptions { // `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the // Cortex-M7 (vfp5) - // `+d16` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers + // `-d32` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers // available - // `+fp-only-sp` The Cortex-M4 only supports single precision floating point operations + // `-fp64` The Cortex-M4 only supports single precision floating point operations // whereas in the Cortex-M7 double precision is optional // // Reference: // ARMv7-M Architecture Reference Manual - A2.5 The optional floating-point extension - features: "+vfp4,+d16,+fp-only-sp".to_string(), + features: "+vfp4,-d32,-fp64".to_string(), max_atomic_width: Some(32), .. super::thumb_base::opts() } diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs index 6a3d8e61d7f..7dc30e76dcc 100644 --- a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs +++ b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs @@ -22,7 +22,7 @@ pub fn target() -> TargetResult { // the FPU uses the FPv5 architecture, single-precision instructions // and 16 D registers. // These parameters map to the following LLVM features. - features: "+fp-armv8,+fp-only-sp,+d16".to_string(), + features: "+fp-armv8,-fp64,-d32".to_string(), max_atomic_width: Some(32), .. super::thumb_base::opts() }, From 5324b42a59d9af002e4103ffb410f6345cbdeb7b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 7 Jul 2019 18:18:02 +0200 Subject: [PATCH 15/21] Add function pointer alignment to ARM/Thumb data layout --- src/librustc_target/spec/arm_linux_androideabi.rs | 2 +- src/librustc_target/spec/arm_unknown_linux_gnueabi.rs | 2 +- src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs | 2 +- src/librustc_target/spec/arm_unknown_linux_musleabi.rs | 2 +- src/librustc_target/spec/arm_unknown_linux_musleabihf.rs | 2 +- src/librustc_target/spec/armebv7r_none_eabi.rs | 2 +- src/librustc_target/spec/armebv7r_none_eabihf.rs | 2 +- src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs | 2 +- src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs | 2 +- src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs | 2 +- src/librustc_target/spec/armv6_unknown_freebsd.rs | 2 +- src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs | 2 +- src/librustc_target/spec/armv7_apple_ios.rs | 2 +- src/librustc_target/spec/armv7_linux_androideabi.rs | 2 +- src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs | 2 +- src/librustc_target/spec/armv7_unknown_freebsd.rs | 2 +- src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs | 2 +- src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs | 2 +- src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs | 2 +- src/librustc_target/spec/armv7r_none_eabi.rs | 2 +- src/librustc_target/spec/armv7r_none_eabihf.rs | 2 +- src/librustc_target/spec/armv7s_apple_ios.rs | 2 +- src/librustc_target/spec/thumbv6m_none_eabi.rs | 2 +- src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs | 2 +- src/librustc_target/spec/thumbv7em_none_eabi.rs | 2 +- src/librustc_target/spec/thumbv7em_none_eabihf.rs | 2 +- src/librustc_target/spec/thumbv7m_none_eabi.rs | 2 +- src/librustc_target/spec/thumbv7neon_linux_androideabi.rs | 2 +- src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs | 2 +- src/librustc_target/spec/thumbv8m_base_none_eabi.rs | 2 +- src/librustc_target/spec/thumbv8m_main_none_eabi.rs | 2 +- src/librustc_target/spec/thumbv8m_main_none_eabihf.rs | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/librustc_target/spec/arm_linux_androideabi.rs b/src/librustc_target/spec/arm_linux_androideabi.rs index bb066dc9ad8..c02edabd886 100644 --- a/src/librustc_target/spec/arm_linux_androideabi.rs +++ b/src/librustc_target/spec/arm_linux_androideabi.rs @@ -11,7 +11,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "android".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs index 2f835420148..1d5751c1f71 100644 --- a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs +++ b/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs @@ -8,7 +8,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs index cd4b2e1c922..8eb19a6518a 100644 --- a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs @@ -8,7 +8,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs b/src/librustc_target/spec/arm_unknown_linux_musleabi.rs index 606c3f19060..5c40b6fb89f 100644 --- a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs +++ b/src/librustc_target/spec/arm_unknown_linux_musleabi.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "musl".to_string(), diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs index d22156bc328..496a0c4a43a 100644 --- a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "musl".to_string(), diff --git a/src/librustc_target/spec/armebv7r_none_eabi.rs b/src/librustc_target/spec/armebv7r_none_eabi.rs index 86c62daa618..0b41b920e58 100644 --- a/src/librustc_target/spec/armebv7r_none_eabi.rs +++ b/src/librustc_target/spec/armebv7r_none_eabi.rs @@ -9,7 +9,7 @@ pub fn target() -> TargetResult { target_endian: "big".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: "".to_string(), diff --git a/src/librustc_target/spec/armebv7r_none_eabihf.rs b/src/librustc_target/spec/armebv7r_none_eabihf.rs index ff8e43100e2..5f1bfdce355 100644 --- a/src/librustc_target/spec/armebv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armebv7r_none_eabihf.rs @@ -9,7 +9,7 @@ pub fn target() -> TargetResult { target_endian: "big".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs index e7da24843cc..264bf8d871d 100644 --- a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs +++ b/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs @@ -7,7 +7,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs index ea586f42c26..d0f1222d87a 100644 --- a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs +++ b/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs @@ -7,7 +7,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs b/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs index dae5c8c3d75..9c08a7741a6 100644 --- a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs +++ b/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs @@ -10,7 +10,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "musl".to_string(), diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/src/librustc_target/spec/armv6_unknown_freebsd.rs index a90590a39e7..efbbee959ed 100644 --- a/src/librustc_target/spec/armv6_unknown_freebsd.rs +++ b/src/librustc_target/spec/armv6_unknown_freebsd.rs @@ -7,7 +7,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "freebsd".to_string(), target_env: "gnueabihf".to_string(), diff --git a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs index b056776bdfb..b76c39ac75b 100644 --- a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs +++ b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs @@ -8,7 +8,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "netbsd".to_string(), target_env: "eabihf".to_string(), diff --git a/src/librustc_target/spec/armv7_apple_ios.rs b/src/librustc_target/spec/armv7_apple_ios.rs index 2052d17403d..c1e1caf8e2e 100644 --- a/src/librustc_target/spec/armv7_apple_ios.rs +++ b/src/librustc_target/spec/armv7_apple_ios.rs @@ -8,7 +8,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(), + data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(), arch: "arm".to_string(), target_os: "ios".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/armv7_linux_androideabi.rs b/src/librustc_target/spec/armv7_linux_androideabi.rs index 4c13c6669c3..e22a853814a 100644 --- a/src/librustc_target/spec/armv7_linux_androideabi.rs +++ b/src/librustc_target/spec/armv7_linux_androideabi.rs @@ -20,7 +20,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "android".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs b/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs index c03f4b544ed..7065d30a5be 100644 --- a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs @@ -13,7 +13,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "cloudabi".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/armv7_unknown_freebsd.rs b/src/librustc_target/spec/armv7_unknown_freebsd.rs index 0509ddab048..219b06362f3 100644 --- a/src/librustc_target/spec/armv7_unknown_freebsd.rs +++ b/src/librustc_target/spec/armv7_unknown_freebsd.rs @@ -7,7 +7,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "freebsd".to_string(), target_env: "gnueabihf".to_string(), diff --git a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs index ff34fda7502..1dd53b1b422 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs @@ -10,7 +10,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs index de22fbbaa4c..ee8e48e3e75 100644 --- a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs @@ -12,7 +12,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "musl".to_string(), diff --git a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs index a654e40d0ae..1d63b0261c1 100644 --- a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs +++ b/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs @@ -7,7 +7,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "netbsd".to_string(), target_env: "eabihf".to_string(), diff --git a/src/librustc_target/spec/armv7r_none_eabi.rs b/src/librustc_target/spec/armv7r_none_eabi.rs index 19d332467de..814ca1d77ac 100644 --- a/src/librustc_target/spec/armv7r_none_eabi.rs +++ b/src/librustc_target/spec/armv7r_none_eabi.rs @@ -9,7 +9,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: "".to_string(), diff --git a/src/librustc_target/spec/armv7r_none_eabihf.rs b/src/librustc_target/spec/armv7r_none_eabihf.rs index 24772475e04..decf1a01e0b 100644 --- a/src/librustc_target/spec/armv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armv7r_none_eabihf.rs @@ -9,7 +9,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: "".to_string(), diff --git a/src/librustc_target/spec/armv7s_apple_ios.rs b/src/librustc_target/spec/armv7s_apple_ios.rs index 29e290285e4..55e2a876865 100644 --- a/src/librustc_target/spec/armv7s_apple_ios.rs +++ b/src/librustc_target/spec/armv7s_apple_ios.rs @@ -8,7 +8,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(), + data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".to_string(), arch: "arm".to_string(), target_os: "ios".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/thumbv6m_none_eabi.rs b/src/librustc_target/spec/thumbv6m_none_eabi.rs index 2ab61b57f6b..28353552fc7 100644 --- a/src/librustc_target/spec/thumbv6m_none_eabi.rs +++ b/src/librustc_target/spec/thumbv6m_none_eabi.rs @@ -8,7 +8,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs index 310fac31c0c..886e3188272 100644 --- a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs +++ b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs @@ -22,7 +22,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:w-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "windows".to_string(), target_env: "msvc".to_string(), diff --git a/src/librustc_target/spec/thumbv7em_none_eabi.rs b/src/librustc_target/spec/thumbv7em_none_eabi.rs index 97114c342cd..4e2f9b91b0d 100644 --- a/src/librustc_target/spec/thumbv7em_none_eabi.rs +++ b/src/librustc_target/spec/thumbv7em_none_eabi.rs @@ -17,7 +17,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/thumbv7em_none_eabihf.rs b/src/librustc_target/spec/thumbv7em_none_eabihf.rs index 5c386a00ba4..c510be519c0 100644 --- a/src/librustc_target/spec/thumbv7em_none_eabihf.rs +++ b/src/librustc_target/spec/thumbv7em_none_eabihf.rs @@ -16,7 +16,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/thumbv7m_none_eabi.rs b/src/librustc_target/spec/thumbv7m_none_eabi.rs index daf25b16d58..9c9868ef37c 100644 --- a/src/librustc_target/spec/thumbv7m_none_eabi.rs +++ b/src/librustc_target/spec/thumbv7m_none_eabi.rs @@ -8,7 +8,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs b/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs index e248b930e6e..f3142ef6002 100644 --- a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs +++ b/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs @@ -20,7 +20,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "android".to_string(), target_env: "".to_string(), diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs index bef62b0a2eb..5524bc9ab66 100644 --- a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs @@ -13,7 +13,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "linux".to_string(), target_env: "gnu".to_string(), diff --git a/src/librustc_target/spec/thumbv8m_base_none_eabi.rs b/src/librustc_target/spec/thumbv8m_base_none_eabi.rs index be8a476db4d..0b4750093cc 100644 --- a/src/librustc_target/spec/thumbv8m_base_none_eabi.rs +++ b/src/librustc_target/spec/thumbv8m_base_none_eabi.rs @@ -8,7 +8,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabi.rs b/src/librustc_target/spec/thumbv8m_main_none_eabi.rs index 49ab643d484..acce424136d 100644 --- a/src/librustc_target/spec/thumbv8m_main_none_eabi.rs +++ b/src/librustc_target/spec/thumbv8m_main_none_eabi.rs @@ -9,7 +9,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: String::new(), diff --git a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs index 7dc30e76dcc..455d56b095b 100644 --- a/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs +++ b/src/librustc_target/spec/thumbv8m_main_none_eabihf.rs @@ -9,7 +9,7 @@ pub fn target() -> TargetResult { target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), - data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(), arch: "arm".to_string(), target_os: "none".to_string(), target_env: String::new(), From 8789c9e59596c5f89c6be6b82a880e016d6c2f31 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 7 Jul 2019 18:41:28 +0200 Subject: [PATCH 16/21] Strip function pointer alignment for older LLVM versions --- src/librustc_codegen_llvm/context.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 6a61b180de4..2b68eb53a4a 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -1,5 +1,6 @@ use crate::attributes; use crate::llvm; +use crate::llvm_util; use crate::debuginfo; use crate::value::Value; use rustc::dep_graph::DepGraphSafe; @@ -140,6 +141,11 @@ pub fn is_pie_binary(sess: &Session) -> bool { !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC } +fn strip_function_ptr_alignment(data_layout: String) -> String { + // FIXME: Make this more general. + data_layout.replace("-Fi8-", "-") +} + pub unsafe fn create_module( tcx: TyCtxt<'_>, llcx: &'ll llvm::Context, @@ -149,14 +155,19 @@ pub unsafe fn create_module( let mod_name = SmallCStr::new(mod_name); let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx); + let mut target_data_layout = sess.target.target.data_layout.clone(); + if llvm_util::get_major_version() < 9 { + target_data_layout = strip_function_ptr_alignment(target_data_layout); + } + // Ensure the data-layout values hardcoded remain the defaults. if sess.target.target.options.is_builtin { let tm = crate::back::write::create_informational_target_machine(&tcx.sess, false); llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm); llvm::LLVMRustDisposeTargetMachine(tm); - let data_layout = llvm::LLVMGetDataLayout(llmod); - let data_layout = str::from_utf8(CStr::from_ptr(data_layout).to_bytes()) + let llvm_data_layout = llvm::LLVMGetDataLayout(llmod); + let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes()) .ok().expect("got a non-UTF8 data-layout from LLVM"); // Unfortunately LLVM target specs change over time, and right now we @@ -177,16 +188,16 @@ pub unsafe fn create_module( let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or(""); let custom_llvm_used = cfg_llvm_root.trim() != ""; - if !custom_llvm_used && sess.target.target.data_layout != data_layout { + if !custom_llvm_used && target_data_layout != llvm_data_layout { bug!("data-layout for builtin `{}` target, `{}`, \ differs from LLVM default, `{}`", sess.target.target.llvm_target, - sess.target.target.data_layout, - data_layout); + target_data_layout, + llvm_data_layout); } } - let data_layout = SmallCStr::new(&sess.target.target.data_layout); + let data_layout = SmallCStr::new(&target_data_layout); llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr()); let llvm_target = SmallCStr::new(&sess.target.target.llvm_target); From 5c95f5fa6b6024ea0b8ed162e5d2c46c41aea1b0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 7 Jul 2019 19:08:40 +0200 Subject: [PATCH 17/21] Fix float add/mul reduction codegen The accumulator is now respected for unordered reductions. --- src/librustc_codegen_llvm/common.rs | 4 ++++ src/librustc_codegen_llvm/intrinsic.rs | 5 +++-- src/librustc_codegen_llvm/llvm/ffi.rs | 1 + src/librustc_codegen_ssa/traits/consts.rs | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 3b2701b893b..e9f25e6344b 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -249,6 +249,10 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.const_uint(self.type_i8(), i as u64) } + fn const_real(&self, t: &'ll Type, val: f64) -> &'ll Value { + unsafe { llvm::LLVMConstReal(t, val) } + } + fn const_struct( &self, elts: &[&'ll Value], diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 69f8356f669..dd6cfd7e29e 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1663,9 +1663,10 @@ fn generic_simd_intrinsic( acc } else { // unordered arithmetic reductions do not: + let identity_acc = if $name.contains("mul") { 1.0 } else { 0.0 }; match f.bit_width() { - 32 => bx.const_undef(bx.type_f32()), - 64 => bx.const_undef(bx.type_f64()), + 32 => bx.const_real(bx.type_f32(), identity_acc), + 64 => bx.const_real(bx.type_f64(), identity_acc), v => { return_error!(r#" unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 75f639ec3ec..4bf0faa1ec3 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -715,6 +715,7 @@ extern "C" { // Operations on scalar constants pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value; pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value; + pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value; pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong; pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool, high: &mut u64, low: &mut u64) -> bool; diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs index 46286b5329e..248fadfaf0f 100644 --- a/src/librustc_codegen_ssa/traits/consts.rs +++ b/src/librustc_codegen_ssa/traits/consts.rs @@ -17,6 +17,7 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn const_u64(&self, i: u64) -> Self::Value; fn const_usize(&self, i: u64) -> Self::Value; fn const_u8(&self, i: u8) -> Self::Value; + fn const_real(&self, t: Self::Type, val: f64) -> Self::Value; fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value; From ac560258e36659d542850651fc1b79e4db2eb29d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 7 Jul 2019 20:22:56 +0200 Subject: [PATCH 18/21] Adjust codegen tests for DISPFlagMainSubprogram --- src/test/codegen/mainsubprogram.rs | 2 +- src/test/codegen/mainsubprogramstart.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/codegen/mainsubprogram.rs b/src/test/codegen/mainsubprogram.rs index 7f1b0e17f87..790db33437b 100644 --- a/src/test/codegen/mainsubprogram.rs +++ b/src/test/codegen/mainsubprogram.rs @@ -7,7 +7,7 @@ // compile-flags: -g -C no-prepopulate-passes // CHECK-LABEL: @main -// CHECK: {{.*}}DISubprogram{{.*}}name: "main",{{.*}}DIFlagMainSubprogram{{.*}} +// CHECK: {{.*}}DISubprogram{{.*}}name: "main",{{.*}}DI{{(SP)?}}FlagMainSubprogram{{.*}} pub fn main() { } diff --git a/src/test/codegen/mainsubprogramstart.rs b/src/test/codegen/mainsubprogramstart.rs index b03290af0e3..d4de9f59ac2 100644 --- a/src/test/codegen/mainsubprogramstart.rs +++ b/src/test/codegen/mainsubprogramstart.rs @@ -6,7 +6,7 @@ #![feature(start)] // CHECK-LABEL: @main -// CHECK: {{.*}}DISubprogram{{.*}}name: "start",{{.*}}DIFlagMainSubprogram{{.*}} +// CHECK: {{.*}}DISubprogram{{.*}}name: "start",{{.*}}DI{{(SP)?}}FlagMainSubprogram{{.*}} #[start] fn start(_: isize, _: *const *const u8) -> isize { From 74a39a39a4a0650d110083afa6e0b226f7b61ca9 Mon Sep 17 00:00:00 2001 From: Eric Rahm Date: Fri, 14 Jun 2019 10:58:39 -0700 Subject: [PATCH 19/21] Emit warning when trying to use PGO in conjunction with unwinding on Windows. --- src/librustc/session/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3cbf0ee213a..b17ba8de730 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1303,15 +1303,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } // PGO does not work reliably with panic=unwind on Windows. Let's make it - // an error to combine the two for now. It always runs into an assertions + // a warning to combine the two for now. It always runs into an assertions // if LLVM is built with assertions, but without assertions it sometimes // does not crash and will probably generate a corrupted binary. if sess.opts.cg.profile_generate.enabled() && sess.target.target.options.is_like_msvc && sess.panic_strategy() == PanicStrategy::Unwind { - sess.err("Profile-guided optimization does not yet work in conjunction \ - with `-Cpanic=unwind` on Windows when targeting MSVC. \ - See https://github.com/rust-lang/rust/issues/61002 for details."); + sess.warn("Profile-guided optimization does not yet work in conjunction \ + with `-Cpanic=unwind` on Windows when targeting MSVC. \ + See https://github.com/rust-lang/rust/issues/61002 for details."); } } From 4c22e48f6e63f4c6274a59283e845ca4a96c5de2 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 9 Jul 2019 15:17:47 -0700 Subject: [PATCH 20/21] Tracking issue 62543 for iter_partition_in_place --- src/libcore/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index b123d4a1469..cb93d78af35 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1536,7 +1536,7 @@ pub trait Iterator { /// assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds /// ``` - #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "0")] + #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")] fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize where Self: Sized + DoubleEndedIterator, From 7171c83ab234926d620c4869eeac90b393833ef2 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 9 Jul 2019 15:18:33 -0700 Subject: [PATCH 21/21] Tracking issue 62544 for iter_is_partitioned --- src/libcore/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index cb93d78af35..6eddac672c1 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1595,7 +1595,7 @@ pub trait Iterator { /// assert!("Iterator".chars().is_partitioned(char::is_uppercase)); /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase)); /// ``` - #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "0")] + #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "62544")] fn is_partitioned

(mut self, mut predicate: P) -> bool where Self: Sized,