Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 12 pull requests #77381

Merged
merged 27 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ecacc75
Add advance_by and advance_back_by
timvermeulen Sep 19, 2020
c29a29c
Defer Apple SDKROOT detection to link time.
ehuss Sep 25, 2020
de725fe
Remove note about missing ios/tvos targets in platform docs.
ehuss Sep 25, 2020
7420d7a
Move add_apple_sdk out of add_pre_link_args.
ehuss Sep 27, 2020
a4783de
const evaluatable: improve `TooGeneric` handling
lcnr Sep 28, 2020
db5b70f
move candidate_from_obligation_no_cache
lcnr Sep 28, 2020
5829560
Rename AllocErr to AllocError
Sep 24, 2020
46d8c4b
Fix recursive nonterminal expansion during pretty-print/reparse check
Aaron1011 Sep 24, 2020
c6107c5
Don't fire `const_item_mutation` lint on writes through a pointer
Aaron1011 Sep 29, 2020
15c3573
Update cargo
ehuss Sep 29, 2020
d061fee
Stable hashing: add comments and tests concerning platform-independence
tgnottingham Sep 29, 2020
ce6c25d
References to ZSTs may be at arbitrary aligned addresses
oli-obk Sep 30, 2020
609786d
Validate `rustc_args_required_const`
varkor Sep 29, 2020
05d0b96
Add test for error message
camelid Sep 30, 2020
b2ce3e5
Remove trailing space in error message
camelid Sep 30, 2020
8bd4ed9
Rollup merge of #76909 - timvermeulen:advance_by, r=Amanieu
Dylan-DPC Oct 1, 2020
8ccc063
Rollup merge of #77153 - Aaron1011:fix/better-recursive-expand, r=pet…
Dylan-DPC Oct 1, 2020
37df40b
Rollup merge of #77202 - ehuss:defer-apple-sdkroot, r=petrochenkov
Dylan-DPC Oct 1, 2020
f235594
Rollup merge of #77303 - lcnr:const-evaluatable-TooGeneric, r=oli-obk…
Dylan-DPC Oct 1, 2020
6d3cfd9
Rollup merge of #77305 - lcnr:candidate_from_obligation, r=davidtwco
Dylan-DPC Oct 1, 2020
70740b1
Rollup merge of #77315 - exrook:rename-allocerror, r=joshtriplett
Dylan-DPC Oct 1, 2020
0044a9c
Rollup merge of #77319 - tgnottingham:siphasher_endianness, r=nnether…
Dylan-DPC Oct 1, 2020
73258f8
Rollup merge of #77324 - Aaron1011:fix/const-item-mutation-ptr, r=pet…
Dylan-DPC Oct 1, 2020
849e563
Rollup merge of #77343 - varkor:rustc_args_required_const-validation,…
Dylan-DPC Oct 1, 2020
ffb771b
Rollup merge of #77349 - ehuss:update-cargo, r=ehuss
Dylan-DPC Oct 1, 2020
cc1513b
Rollup merge of #77360 - oli-obk:zst_const_pat_regression, r=RalfJung
Dylan-DPC Oct 1, 2020
85e77ed
Rollup merge of #77371 - camelid:remove-extra-space-in-diagnostic, r=…
Dylan-DPC Oct 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,9 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
// NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
add_pre_link_args(cmd, sess, flavor);

// NO-OPT-OUT, OBJECT-FILES-NO
add_apple_sdk(cmd, sess, flavor);

// NO-OPT-OUT
add_link_script(cmd, sess, tmpdir, crate_type);

Expand Down Expand Up @@ -2083,3 +2086,86 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
config::Lto::No | config::Lto::ThinLocal => false,
}
}

fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
let arch = &sess.target.target.arch;
let os = &sess.target.target.target_os;
let llvm_target = &sess.target.target.llvm_target;
if sess.target.target.target_vendor != "apple"
|| !matches!(os.as_str(), "ios" | "tvos")
|| flavor != LinkerFlavor::Gcc
{
return;
}
let sdk_name = match (arch.as_str(), os.as_str()) {
("aarch64", "tvos") => "appletvos",
("x86_64", "tvos") => "appletvsimulator",
("arm", "ios") => "iphoneos",
("aarch64", "ios") => "iphoneos",
("x86", "ios") => "iphonesimulator",
("x86_64", "ios") if llvm_target.contains("macabi") => "macosx10.15",
("x86_64", "ios") => "iphonesimulator",
_ => {
sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
return;
}
};
let sdk_root = match get_apple_sdk_root(sdk_name) {
Ok(s) => s,
Err(e) => {
sess.err(&e);
return;
}
};
let arch_name = llvm_target.split('-').next().expect("LLVM target must have a hyphen");
cmd.args(&["-arch", arch_name, "-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
}

fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
// Following what clang does
// (https://github.com/llvm/llvm-project/blob/
// 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
// to allow the SDK path to be set. (For clang, xcrun sets
// SDKROOT; for rustc, the user or build system can set it, or we
// can fall back to checking for xcrun on PATH.)
if let Ok(sdkroot) = env::var("SDKROOT") {
let p = Path::new(&sdkroot);
match sdk_name {
// Ignore `SDKROOT` if it's clearly set for the wrong platform.
"appletvos"
if sdkroot.contains("TVSimulator.platform")
|| sdkroot.contains("MacOSX.platform") => {}
"appletvsimulator"
if sdkroot.contains("TVOS.platform") || sdkroot.contains("MacOSX.platform") => {}
"iphoneos"
if sdkroot.contains("iPhoneSimulator.platform")
|| sdkroot.contains("MacOSX.platform") => {}
"iphonesimulator"
if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("MacOSX.platform") => {
}
"macosx10.15"
if sdkroot.contains("iPhoneOS.platform")
|| sdkroot.contains("iPhoneSimulator.platform") => {}
// Ignore `SDKROOT` if it's not a valid path.
_ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
_ => return Ok(sdkroot),
}
}
let res =
Command::new("xcrun").arg("--show-sdk-path").arg("-sdk").arg(sdk_name).output().and_then(
|output| {
if output.status.success() {
Ok(String::from_utf8(output.stdout).unwrap())
} else {
let error = String::from_utf8(output.stderr);
let error = format!("process exit with error: {}", error.unwrap());
Err(io::Error::new(io::ErrorKind::Other, &error[..]))
}
},
);

match res {
Ok(output) => Ok(output.trim().to_string()),
Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
}
}
25 changes: 19 additions & 6 deletions compiler/rustc_data_structures/src/sip128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,28 @@ impl SipHasher128 {

// A specialized write function for values with size <= 8.
//
// The hashing of multi-byte integers depends on endianness. E.g.:
// The input must be zero-extended to 64-bits by the caller. This extension
// isn't hashed, but the implementation requires it for correctness.
//
// This function, given the same integer size and value, has the same effect
// on both little- and big-endian hardware. It operates on values without
// depending on their sequence in memory, so is independent of endianness.
//
// However, we want SipHasher128 to be platform-dependent, in order to be
// consistent with the platform-dependent SipHasher in libstd. In other
// words, we want:
//
// - little-endian: `write_u32(0xDDCCBBAA)` == `write([0xAA, 0xBB, 0xCC, 0xDD])`
// - big-endian: `write_u32(0xDDCCBBAA)` == `write([0xDD, 0xCC, 0xBB, 0xAA])`
//
// This function does the right thing for little-endian hardware. On
// big-endian hardware `x` must be byte-swapped first to give the right
// behaviour. After any byte-swapping, the input must be zero-extended to
// 64-bits. The caller is responsible for the byte-swapping and
// zero-extension.
// Therefore, in order to produce endian-dependent results, SipHasher128's
// `write_xxx` Hasher trait methods byte-swap `x` prior to zero-extending.
//
// If clients of SipHasher128 itself want platform-independent results, they
// *also* must byte-swap integer inputs before invoking the `write_xxx`
// methods on big-endian hardware (that is, two byte-swaps must occur--one
// in the client, and one in SipHasher128). Additionally, they must extend
// `usize` and `isize` types to 64 bits on 32-bit systems.
#[inline]
fn short_write<T>(&mut self, _x: T, x: u64) {
let size = mem::size_of::<T>();
Expand Down
56 changes: 45 additions & 11 deletions compiler/rustc_data_structures/src/sip128/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::*;

use std::hash::{Hash, Hasher};
use std::{mem, slice};

// Hash just the bytes of the slice, without length prefix
struct Bytes<'a>(&'a [u8]);
Expand Down Expand Up @@ -399,20 +398,55 @@ fn test_hash_no_concat_alias() {
}

#[test]
fn test_write_short_works() {
let test_usize = 0xd0c0b0a0usize;
fn test_short_write_works() {
let test_u8 = 0xFF_u8;
let test_u16 = 0x1122_u16;
let test_u32 = 0x22334455_u32;
let test_u64 = 0x33445566_778899AA_u64;
let test_u128 = 0x11223344_55667788_99AABBCC_DDEEFF77_u128;
let test_usize = 0xD0C0B0A0_usize;

let test_i8 = -1_i8;
let test_i16 = -2_i16;
let test_i32 = -3_i32;
let test_i64 = -4_i64;
let test_i128 = -5_i128;
let test_isize = -6_isize;

let mut h1 = SipHasher128::new_with_keys(0, 0);
h1.write_usize(test_usize);
h1.write(b"bytes");
h1.write(b"string");
h1.write_u8(0xFFu8);
h1.write_u8(0x01u8);
h1.write_u8(test_u8);
h1.write_u16(test_u16);
h1.write_u32(test_u32);
h1.write_u64(test_u64);
h1.write_u128(test_u128);
h1.write_usize(test_usize);
h1.write_i8(test_i8);
h1.write_i16(test_i16);
h1.write_i32(test_i32);
h1.write_i64(test_i64);
h1.write_i128(test_i128);
h1.write_isize(test_isize);

let mut h2 = SipHasher128::new_with_keys(0, 0);
h2.write(unsafe {
slice::from_raw_parts(&test_usize as *const _ as *const u8, mem::size_of::<usize>())
});
h2.write(b"bytes");
h2.write(b"string");
h2.write(&[0xFFu8, 0x01u8]);
assert_eq!(h1.finish128(), h2.finish128());
h2.write(&test_u8.to_ne_bytes());
h2.write(&test_u16.to_ne_bytes());
h2.write(&test_u32.to_ne_bytes());
h2.write(&test_u64.to_ne_bytes());
h2.write(&test_u128.to_ne_bytes());
h2.write(&test_usize.to_ne_bytes());
h2.write(&test_i8.to_ne_bytes());
h2.write(&test_i16.to_ne_bytes());
h2.write(&test_i32.to_ne_bytes());
h2.write(&test_i64.to_ne_bytes());
h2.write(&test_i128.to_ne_bytes());
h2.write(&test_isize.to_ne_bytes());

let h1_hash = h1.finish128();
let h2_hash = h2.finish128();

assert_eq!(h1_hash, h2_hash);
}
6 changes: 5 additions & 1 deletion compiler/rustc_data_structures/src/stable_hasher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ use smallvec::SmallVec;
use std::hash::{BuildHasher, Hash, Hasher};
use std::mem;

#[cfg(test)]
mod tests;

/// When hashing something that ends up affecting properties like symbol names,
/// we want these symbol names to be calculated independently of other factors
/// like what architecture you're compiling *from*.
Expand Down Expand Up @@ -129,7 +132,8 @@ impl Hasher for StableHasher {
fn write_isize(&mut self, i: isize) {
// Always treat isize as i64 so we get the same results on 32 and 64 bit
// platforms. This is important for symbol hashes when cross compiling,
// for example.
// for example. Sign extending here is preferable as it means that the
// same negative number hashes the same on both 32 and 64 bit platforms.
self.state.write_i64((i as i64).to_le());
}
}
Expand Down
73 changes: 73 additions & 0 deletions compiler/rustc_data_structures/src/stable_hasher/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use super::*;

// The tests below compare the computed hashes to particular expected values
// in order to test that we produce the same results on different platforms,
// regardless of endianness and `usize` and `isize` size differences (this
// of course assumes we run these tests on platforms that differ in those
// ways). The expected values depend on the hashing algorithm used, so they
// need to be updated whenever StableHasher changes its hashing algorithm.

#[test]
fn test_hash_integers() {
// Test that integers are handled consistently across platforms.
let test_u8 = 0xAB_u8;
let test_u16 = 0xFFEE_u16;
let test_u32 = 0x445577AA_u32;
let test_u64 = 0x01234567_13243546_u64;
let test_u128 = 0x22114433_66557788_99AACCBB_EEDDFF77_u128;
let test_usize = 0xD0C0B0A0_usize;

let test_i8 = -100_i8;
let test_i16 = -200_i16;
let test_i32 = -300_i32;
let test_i64 = -400_i64;
let test_i128 = -500_i128;
let test_isize = -600_isize;

let mut h = StableHasher::new();
test_u8.hash(&mut h);
test_u16.hash(&mut h);
test_u32.hash(&mut h);
test_u64.hash(&mut h);
test_u128.hash(&mut h);
test_usize.hash(&mut h);
test_i8.hash(&mut h);
test_i16.hash(&mut h);
test_i32.hash(&mut h);
test_i64.hash(&mut h);
test_i128.hash(&mut h);
test_isize.hash(&mut h);

// This depends on the hashing algorithm. See note at top of file.
let expected = (2736651863462566372, 8121090595289675650);

assert_eq!(h.finalize(), expected);
}

#[test]
fn test_hash_usize() {
// Test that usize specifically is handled consistently across platforms.
let test_usize = 0xABCDEF01_usize;

let mut h = StableHasher::new();
test_usize.hash(&mut h);

// This depends on the hashing algorithm. See note at top of file.
let expected = (5798740672699530587, 11186240177685111648);

assert_eq!(h.finalize(), expected);
}

#[test]
fn test_hash_isize() {
// Test that isize specifically is handled consistently across platforms.
let test_isize = -7_isize;

let mut h = StableHasher::new();
test_isize.hash(&mut h);

// This depends on the hashing algorithm. See note at top of file.
let expected = (14721296605626097289, 11385941877786388409);

assert_eq!(h.finalize(), expected);
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ impl<'tcx> ty::TyS<'tcx> {
let n = tcx.lift(&n).unwrap();
match n.try_eval_usize(tcx, ty::ParamEnv::empty()) {
_ if t.is_simple_ty() => format!("array `{}`", self).into(),
Some(n) => format!("array of {} element{} ", n, pluralize!(n)).into(),
Some(n) => format!("array of {} element{}", n, pluralize!(n)).into(),
None => "array".into(),
}
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_mir/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, subst::Subst, TyCtxt};
use rustc_span::source_map::Span;
use rustc_target::abi::{Abi, LayoutOf};
use std::convert::TryInto;
use std::convert::{TryFrom, TryInto};

pub fn note_on_undefined_behavior_error() -> &'static str {
"The rules on what exactly is undefined behavior aren't clear, \
Expand Down Expand Up @@ -148,10 +148,10 @@ pub(super) fn op_to_const<'tcx>(
Scalar::Raw { data, .. } => {
assert!(mplace.layout.is_zst());
assert_eq!(
data,
mplace.layout.align.abi.bytes().into(),
"this MPlaceTy must come from `try_as_mplace` being used on a zst, so we know what
value this integer address must have",
u64::try_from(data).unwrap() % mplace.layout.align.abi.bytes(),
0,
"this MPlaceTy must come from a validated constant, thus we can assume the \
alignment is correct",
);
ConstValue::Scalar(Scalar::zst())
}
Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_mir/src/transform/check_const_item_mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,15 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> {
// so emitting a lint would be redundant.
if !lhs.projection.is_empty() {
if let Some(def_id) = self.is_const_item(lhs.local) {
self.lint_const_item_usage(def_id, loc, |lint| {
let mut lint = lint.build("attempting to modify a `const` item");
lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified");
lint
})
// Don't lint on writes through a pointer
// (e.g. `unsafe { *FOO = 0; *BAR.field = 1; }`)
if !matches!(lhs.projection.last(), Some(PlaceElem::Deref)) {
self.lint_const_item_usage(def_id, loc, |lint| {
let mut lint = lint.build("attempting to modify a `const` item");
lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified");
lint
})
}
}
}
// We are looking for MIR of the form:
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Vec<usize>> {
LitKind::Int(a, _) => {
ret.push(a as usize);
}
_ => return None,
_ => bug!("invalid arg index"),
}
}
Some(ret)
Expand Down
Loading