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 5 pull requests #70726

Merged
merged 16 commits into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,11 @@ pub fn stream_cargo(
}
// Instruct Cargo to give us json messages on stdout, critically leaving
// stderr as piped so we can get those pretty colors.
let mut message_format = String::from("json-render-diagnostics");
let mut message_format = if builder.config.json_output {
String::from("json")
} else {
String::from("json-render-diagnostics")
};
if let Some(s) = &builder.config.rustc_error_format {
message_format.push_str(",json-diagnostic-");
message_format.push_str(s);
Expand Down
2 changes: 2 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub struct Config {
pub ignore_git: bool,
pub exclude: Vec<PathBuf>,
pub rustc_error_format: Option<String>,
pub json_output: bool,
pub test_compare_mode: bool,
pub llvm_libunwind: bool,

Expand Down Expand Up @@ -415,6 +416,7 @@ impl Config {
let mut config = Config::default_opts();
config.exclude = flags.exclude;
config.rustc_error_format = flags.rustc_error_format;
config.json_output = flags.json_output;
config.on_fail = flags.on_fail;
config.stage = flags.stage;
config.jobs = flags.jobs.map(threads_from_config);
Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub struct Flags {
pub incremental: bool,
pub exclude: Vec<PathBuf>,
pub rustc_error_format: Option<String>,
pub json_output: bool,
pub dry_run: bool,

// This overrides the deny-warnings configuration option,
Expand Down Expand Up @@ -156,6 +157,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
"VALUE",
);
opts.optopt("", "error-format", "rustc error format", "FORMAT");
opts.optflag("", "json-output", "use message-format=json");
opts.optopt(
"",
"llvm-skip-rebuild",
Expand Down Expand Up @@ -503,6 +505,7 @@ Arguments:
dry_run: matches.opt_present("dry-run"),
on_fail: matches.opt_str("on-fail"),
rustc_error_format: matches.opt_str("error-format"),
json_output: matches.opt_present("json-output"),
keep_stage: matches
.opt_strs("keep-stage")
.into_iter()
Expand Down
9 changes: 9 additions & 0 deletions src/ci/docker/dist-various-1/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ RUN ./install-mips-musl.sh
COPY dist-various-1/install-mipsel-musl.sh /build
RUN ./install-mipsel-musl.sh

COPY dist-various-1/install-aarch64-none-elf.sh /build
RUN ./install-aarch64-none-elf.sh

# Suppress some warnings in the openwrt toolchains we downloaded
ENV STAGING_DIR=/tmp

Expand Down Expand Up @@ -140,6 +143,8 @@ ENV TARGETS=$TARGETS,armv5te-unknown-linux-gnueabi
ENV TARGETS=$TARGETS,armv5te-unknown-linux-musleabi
ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabihf
ENV TARGETS=$TARGETS,aarch64-unknown-linux-musl
ENV TARGETS=$TARGETS,aarch64-unknown-none
ENV TARGETS=$TARGETS,aarch64-unknown-none-softfloat
ENV TARGETS=$TARGETS,sparc64-unknown-linux-gnu
ENV TARGETS=$TARGETS,x86_64-unknown-redox
ENV TARGETS=$TARGETS,thumbv6m-none-eabi
Expand Down Expand Up @@ -178,6 +183,10 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
CC_armv7a_none_eabihf=arm-none-eabi-gcc \
CFLAGS_armv7a_none_eabi=-march=armv7-a \
CFLAGS_armv7a_none_eabihf=-march=armv7-a+vfpv3 \
CC_aarch64_unknown_none_softfloat=aarch64-none-elf-gcc \
CFLAGS_aarch64_unknown_none_softfloat=-mstrict-align -march=armv8-a+nofp+nosimd \
CC_aarch64_unknown_none=aarch64-none-elf-gcc \
CFLAGS_aarch64_unknown_none=-mstrict-align -march=armv8-a+fp+simd \
CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \
AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \
CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \
Expand Down
6 changes: 6 additions & 0 deletions src/ci/docker/dist-various-1/install-aarch64-none-elf.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

set -ex

curl -L https://developer.arm.com/-/media/Files/downloads/gnu-a/9.2-2019.12/binrel/gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf.tar.xz \
| tar --extract --xz --strip 1 --directory /usr/local
2 changes: 1 addition & 1 deletion src/doc/unstable-book/src/library-features/llvm-asm.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ llvm_asm!("xor %eax, %eax" ::: "eax");

Input and output operands follow the same format: `:
"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
expressions must be mutable lvalues, or not yet assigned:
expressions must be mutable place, or not yet assigned:

```rust
# #![feature(llvm_asm)]
Expand Down
51 changes: 49 additions & 2 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rustc_middle::ty::query::TyCtxtAt;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::source_map::DUMMY_SP;
use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout};
use rustc_target::abi::{Abi, Align, HasDataLayout, LayoutOf, Size, TargetDataLayout};

use super::{
Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy,
Expand Down Expand Up @@ -210,6 +210,53 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> {
}
}

/// Test if it is valid for a MIR assignment to assign `src`-typed place to `dest`-typed value.
/// This test should be symmetric, as it is primarily about layout compatibility.
pub(super) fn mir_assign_valid_types<'tcx>(
src: TyAndLayout<'tcx>,
dest: TyAndLayout<'tcx>,
) -> bool {
if src.ty == dest.ty {
// Equal types, all is good.
return true;
}
// Type-changing assignments can happen for (at least) two reasons:
// - `&mut T` -> `&T` gets optimized from a reborrow to a mere assignment.
// - Subtyping is used. While all normal lifetimes are erased, higher-ranked lifetime
// bounds are still around and can lead to type differences.
// There is no good way to check the latter, so we compare layouts instead -- but only
// for values with `Scalar`/`ScalarPair` abi.
// FIXME: Do something more accurate, type-based.
match &src.abi {
Abi::Scalar(..) | Abi::ScalarPair(..) => src.layout == dest.layout,
_ => false,
}
}

/// Use the already known layout if given (but sanity check in debug mode),
/// or compute the layout.
#[cfg_attr(not(debug_assertions), inline(always))]
pub(super) fn from_known_layout<'tcx>(
known_layout: Option<TyAndLayout<'tcx>>,
compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
match known_layout {
None => compute(),
Some(known_layout) => {
if cfg!(debug_assertions) {
let check_layout = compute()?;
assert!(
mir_assign_valid_types(check_layout, known_layout),
"expected type differs from actual type.\nexpected: {:?}\nactual: {:?}",
known_layout.ty,
check_layout.ty,
);
}
Ok(known_layout)
}
}
}

impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
pub fn new(
tcx: TyCtxtAt<'tcx>,
Expand Down Expand Up @@ -377,7 +424,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// have to support that case (mostly by skipping all caching).
match frame.locals.get(local).and_then(|state| state.layout.get()) {
None => {
let layout = crate::interpret::operand::from_known_layout(layout, || {
let layout = from_known_layout(layout, || {
let local_ty = frame.body.local_decls[local].ty;
let local_ty =
self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty);
Expand Down
18 changes: 6 additions & 12 deletions src/librustc_mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,13 @@ mod visitor;
pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here

pub use self::eval_context::{Frame, InterpCx, LocalState, LocalValue, StackPopCleanup};

pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};

pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind};

pub use self::intern::{intern_const_alloc_recursive, InternKind};
pub use self::machine::{AllocMap, Machine, MayLeak, StackPopJump};

pub use self::operand::{ImmTy, Immediate, OpTy, Operand, ScalarMaybeUndef};

pub use self::visitor::{MutValueVisitor, ValueVisitor};

pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind};
pub use self::operand::{ImmTy, Immediate, OpTy, Operand};
pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
pub use self::validity::RefTracking;

pub use self::intern::{intern_const_alloc_recursive, InternKind};
pub use self::visitor::{MutValueVisitor, ValueVisitor};

crate use self::intrinsics::eval_nullary_intrinsic;
use eval_context::{from_known_layout, mir_assign_valid_types};
35 changes: 6 additions & 29 deletions src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
//! All high-level functions to read from memory work on operands as sources.

use std::convert::TryFrom;
use std::fmt::Write;

use super::{InterpCx, MPlaceTy, Machine, MemPlace, Place, PlaceTy};
use rustc_hir::def::Namespace;
use rustc_macros::HashStable;
pub use rustc_middle::mir::interpret::ScalarMaybeUndef;
use rustc_middle::mir::interpret::{
sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpResult, Pointer, Scalar,
};
use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt, TyAndLayout};
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer};
use rustc_middle::ty::Ty;
use rustc_middle::{mir, ty};
use rustc_target::abi::{Abi, DiscriminantKind, HasDataLayout, Integer, LayoutOf, Size};
use rustc_target::abi::{VariantIdx, Variants};
use std::fmt::Write;

use super::{
from_known_layout, sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpCx,
InterpResult, MPlaceTy, Machine, MemPlace, Place, PlaceTy, Pointer, Scalar, ScalarMaybeUndef,
};

/// An `Immediate` represents a single immediate self-contained Rust value.
///
Expand Down Expand Up @@ -203,29 +203,6 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
}
}

// Use the existing layout if given (but sanity check in debug mode),
// or compute the layout.
#[inline(always)]
pub(super) fn from_known_layout<'tcx>(
layout: Option<TyAndLayout<'tcx>>,
compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
match layout {
None => compute(),
Some(layout) => {
if cfg!(debug_assertions) {
let layout2 = compute()?;
assert_eq!(
layout.layout, layout2.layout,
"mismatch in layout of supposedly equal-layout types {:?} and {:?}",
layout.ty, layout2.ty
);
}
Ok(layout)
}
}
}

impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Normalice `place.ptr` to a `Pointer` if this is a place and not a ZST.
/// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot.
Expand Down
17 changes: 8 additions & 9 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ use std::hash::Hash;

use rustc_macros::HashStable;
use rustc_middle::mir;
use rustc_middle::mir::interpret::truncate;
use rustc_middle::ty::layout::{PrimitiveExt, TyAndLayout};
use rustc_middle::ty::{self, Ty};
use rustc_target::abi::{Abi, Align, DiscriminantKind, FieldsShape};
use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants};

use super::{
AllocId, AllocMap, Allocation, AllocationExtra, ImmTy, Immediate, InterpCx, InterpResult,
LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, PointerArithmetic, RawConst, Scalar,
ScalarMaybeUndef,
mir_assign_valid_types, truncate, AllocId, AllocMap, Allocation, AllocationExtra, ImmTy,
Immediate, InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer,
PointerArithmetic, RawConst, Scalar, ScalarMaybeUndef,
};

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
Expand Down Expand Up @@ -869,10 +868,10 @@ where
// We do NOT compare the types for equality, because well-typed code can
// actually "transmute" `&mut T` to `&T` in an assignment without a cast.
assert!(
src.layout.layout == dest.layout.layout,
"Layout mismatch when copying!\nsrc: {:#?}\ndest: {:#?}",
src,
dest
mir_assign_valid_types(src.layout, dest.layout),
"type mismatch when copying!\nsrc: {:?},\ndest: {:?}",
src.layout.ty,
dest.layout.ty,
);

// Let us see if the layout is simple so we take a shortcut, avoid force_allocation.
Expand Down Expand Up @@ -923,7 +922,7 @@ where
src: OpTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
if src.layout.layout == dest.layout.layout {
if mir_assign_valid_types(src.layout, dest.layout) {
// Fast path: Just use normal `copy_op`
return self.copy_op(src, dest);
}
Expand Down
2 changes: 2 additions & 0 deletions src/tools/build-manifest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ static TARGETS: &[&str] = &[
"aarch64-unknown-hermit",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"aarch64-unknown-none",
"aarch64-unknown-none-softfloat",
"aarch64-unknown-redox",
"arm-linux-androideabi",
"arm-unknown-linux-gnueabi",
Expand Down
Loading