diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index b9a98236f18a7..6eddac672c158 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_in_place()`]. + /// + /// [`is_partitioned()`]: #method.is_partitioned + /// [`partition_in_place()`]: #method.partition_in_place + /// /// # Examples /// /// Basic usage: @@ -1506,6 +1511,101 @@ 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`. + /// Returns the number of `true` elements found. + /// + /// 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_in_place)] + /// + /// let mut a = [1, 2, 3, 4, 5, 6, 7]; + /// + /// // Partition in-place between evens and odds + /// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0); + /// + /// 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 = "62543")] + 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`. + 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, + /// such that all those that return `true` precede all those that return `false`. + /// + /// See also [`partition()`] and [`partition_in_place()`]. + /// + /// [`partition()`]: #method.partition + /// [`partition_in_place()`]: #method.partition_in_place + /// + /// # 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 = "62544")] + 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. /// diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 4d840ef24c8e6..b7b0849e2129b 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 4b48d1225902b..cbb6423d71010 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; diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3cbf0ee213ae3..b17ba8de73049 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."); } } diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 38d4b7e3f9d85..ff87afe0c444b 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/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 94abf1796d366..33b50401b22f1 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) { diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 3b2701b893bb1..e9f25e6344b06 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/context.rs b/src/librustc_codegen_llvm/context.rs index 6a61b180de430..2b68eb53a4ab9 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); diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index bcb14b8899ec2..62eab0f3d4e69 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/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 69f8356f66920..dd6cfd7e29e4e 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 708ba79ec3ab2..2b22925f44969 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; @@ -794,6 +795,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 +826,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/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs index 46286b5329e43..248fadfaf0f27 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; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 3921bd30df25c..49116f3f171e2 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 f26c3b8ae6afc..8f23c9813f7d9 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/librustc_target/spec/arm_linux_androideabi.rs b/src/librustc_target/spec/arm_linux_androideabi.rs index bb066dc9ad833..c02edabd886fa 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 2f835420148fe..1d5751c1f713b 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 cd4b2e1c92252..8eb19a6518a3f 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 606c3f1906031..5c40b6fb89fd3 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 d22156bc328e0..496a0c4a43a7e 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 86c62daa6180a..0b41b920e5844 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 50ee76414ef9a..5f1bfdce355c1 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(), @@ -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/armv4t_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs index e7da24843cc05..264bf8d871d7a 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 ea586f42c269e..d0f1222d87a5b 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 dae5c8c3d7504..9c08a7741a65e 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 a90590a39e75e..efbbee959ed95 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 b056776bdfb8b..b76c39ac75b8b 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 2052d17403dfd..c1e1caf8e2e76 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 92f1a55e024d7..e22a853814a04 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()); @@ -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 c03f4b544ed0b..7065d30a5beba 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 ca7ab474bef88..219b06362f3f7 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(), @@ -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 f0952cccb2087..1dd53b1b4229f 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(), @@ -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 a9974f6b80c93..ee8e48e3e751c 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(), @@ -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 e2d55e9317b76..1d63b0261c1a4 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(), @@ -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_eabi.rs b/src/librustc_target/spec/armv7r_none_eabi.rs index 19d332467dec5..814ca1d77ac7e 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 06ef9f3ec4e37..decf1a01e0b14 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(), @@ -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/armv7s_apple_ios.rs b/src/librustc_target/spec/armv7s_apple_ios.rs index 29e290285e4a9..55e2a876865e3 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/mod.rs b/src/librustc_target/spec/mod.rs index 75821aba4706e..3054ffabb4f1f 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, diff --git a/src/librustc_target/spec/thumbv6m_none_eabi.rs b/src/librustc_target/spec/thumbv6m_none_eabi.rs index 2ab61b57f6bb6..28353552fc71a 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 310fac31c0c5b..886e318827262 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 97114c342cdc7..4e2f9b91b0d55 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 e4358bdd7991e..c510be519c0a8 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}; @@ -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(), @@ -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/thumbv7m_none_eabi.rs b/src/librustc_target/spec/thumbv7m_none_eabi.rs index daf25b16d58d6..9c9868ef37c31 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 e248b930e6e4c..f3142ef600239 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 bef62b0a2ebe6..5524bc9ab662e 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 be8a476db4dbc..0b4750093cc2c 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 49ab643d484bc..acce424136db8 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 6a3d8e61d7fe8..455d56b095bfe 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(), @@ -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() }, diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 15c0b6ca5aa81..c0ba41b8af405 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 74ef5cbe9177e..053686b8b1f27 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/print/pprust.rs b/src/libsyntax/print/pprust.rs index 67646cce69b4f..7e099bc4d5095 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/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index a6c8c76cf23f7..f52952ca40274 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/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 0ebef82d37680..cea88f14dcc65 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); diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 66453c08a66ef..16d08ee534edc 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, diff --git a/src/test/codegen/mainsubprogram.rs b/src/test/codegen/mainsubprogram.rs index 7f1b0e17f871e..790db33437b08 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 b03290af0e3b7..d4de9f59ac27a 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 { 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 d5d393b5a6457..bdcdb7922ca57 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-57089.stdout b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout index 0611fcb13f267..84821259d7b9b 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-issue-62325.rs b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs new file mode 100644 index 0000000000000..b7b152e669213 --- /dev/null +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.rs @@ -0,0 +1,27 @@ +// 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)" +// normalize-stdout-test "bytes\((\w+)\.\.[^0]\w*\)" -> "bytes($1..HI)" + +#![feature(proc_macro_hygiene)] + +#[macro_use] +extern crate test_macros; +extern crate dollar_crate_external; + +type S = u8; + +macro_rules! m { () => { + #[print_attr] + struct A(identity!($crate::S)); +}} + +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 new file mode 100644 index 0000000000000..17ad1a7af7046 --- /dev/null +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout @@ -0,0 +1,112 @@ +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: #2 bytes(LO..HI), + }, + Ident { + ident: "A", + span: #2 bytes(LO..HI), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "identity", + span: #2 bytes(LO..HI), + }, + Punct { + ch: '!', + spacing: Alone, + span: #2 bytes(LO..HI), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "$crate", + span: #2 bytes(LO..HI), + }, + Punct { + ch: ':', + spacing: Joint, + span: #2 bytes(LO..HI), + }, + Punct { + ch: ':', + spacing: Alone, + span: #2 bytes(LO..HI), + }, + Ident { + ident: "S", + span: #2 bytes(LO..HI), + }, + ], + span: #2 bytes(LO..HI), + }, + ], + span: #2 bytes(LO..HI), + }, + Punct { + ch: ';', + spacing: Alone, + 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), + }, +] diff --git a/src/test/ui/proc-macro/dollar-crate.stdout b/src/test/ui/proc-macro/dollar-crate.stdout index 3c88ee99842a2..9d9677d49e318 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",