Skip to content
1 change: 0 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3978,7 +3978,6 @@ name = "rustc_middle"
version = "0.0.0"
dependencies = [
"arena",
"backtrace",
"bitflags",
"byteorder",
"log",
Expand Down
1 change: 0 additions & 1 deletion src/librustc_infer/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ impl<'a, 'tcx> At<'a, 'tcx> {
impl<'a, 'tcx> Trace<'a, 'tcx> {
/// Makes `a <: b` where `a` may or may not be expected (if
/// `a_is_expected` is true, then `a` is expected).
/// Makes `expected <: actual`.
pub fn sub<T>(self, a: &T, b: &T) -> InferResult<'tcx, ()>
where
T: Relate<'tcx>,
Expand Down
1 change: 0 additions & 1 deletion src/librustc_middle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ rustc_index = { path = "../librustc_index" }
rustc_serialize = { path = "../libserialize", package = "serialize" }
rustc_ast = { path = "../librustc_ast" }
rustc_span = { path = "../librustc_span" }
backtrace = "0.3.40"
byteorder = { version = "1.3" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
measureme = "0.7.1"
Expand Down
1 change: 1 addition & 0 deletions src/librustc_middle/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
//! This API is completely unstable and subject to change.

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(backtrace)]
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
Expand Down
20 changes: 9 additions & 11 deletions src/librustc_middle/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::ty::query::TyCtxtAt;
use crate::ty::tls;
use crate::ty::{self, layout, Ty};

use backtrace::Backtrace;
use rustc_data_structures::sync::Lock;
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
Expand All @@ -15,7 +14,7 @@ use rustc_macros::HashStable;
use rustc_session::CtfeBacktrace;
use rustc_span::{def_id::DefId, Pos, Span};
use rustc_target::abi::{Align, Size};
use std::{any::Any, fmt, mem};
use std::{any::Any, backtrace::Backtrace, fmt, mem};

#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
pub enum ErrorHandled {
Expand Down Expand Up @@ -219,16 +218,15 @@ impl fmt::Display for InterpErrorInfo<'_> {
}

impl InterpErrorInfo<'_> {
pub fn print_backtrace(&mut self) {
if let Some(ref mut backtrace) = self.backtrace {
print_backtrace(&mut *backtrace);
pub fn print_backtrace(&self) {
if let Some(backtrace) = self.backtrace.as_ref() {
print_backtrace(backtrace);
}
}
}

fn print_backtrace(backtrace: &mut Backtrace) {
backtrace.resolve();
eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
fn print_backtrace(backtrace: &Backtrace) {
eprintln!("\n\nAn error occurred in miri:\n{}", backtrace);
}

impl From<ErrorHandled> for InterpErrorInfo<'_> {
Expand All @@ -255,11 +253,11 @@ impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {

let backtrace = match capture_backtrace {
CtfeBacktrace::Disabled => None,
CtfeBacktrace::Capture => Some(Box::new(Backtrace::new_unresolved())),
CtfeBacktrace::Capture => Some(Box::new(Backtrace::force_capture())),
CtfeBacktrace::Immediate => {
// Print it now.
let mut backtrace = Backtrace::new_unresolved();
print_backtrace(&mut backtrace);
let backtrace = Backtrace::force_capture();
print_backtrace(&backtrace);
None
}
};
Expand Down
16 changes: 6 additions & 10 deletions src/librustc_middle/mir/interpret/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,14 @@ pub trait PointerArithmetic: HasDataLayout {

impl<T: HasDataLayout> PointerArithmetic for T {}

/// `Pointer` is generic over the type that represents a reference to `Allocation`s,
/// thus making it possible for the most convenient representation to be used in
/// each context.
/// Represents a pointer in the Miri engine.
///
/// Defaults to the index based and loosely coupled `AllocId`.
///
/// `Pointer` is also generic over the `Tag` associated with each pointer,
/// `Pointer` is generic over the `Tag` associated with each pointer,
/// which is used to do provenance tracking during execution.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
#[derive(HashStable)]
pub struct Pointer<Tag = (), Id = AllocId> {
pub alloc_id: Id,
pub struct Pointer<Tag = ()> {
pub alloc_id: AllocId,
pub offset: Size,
pub tag: Tag,
}
Expand All @@ -123,7 +119,7 @@ static_assert_size!(Pointer, 16);
// all the Miri types.
// We have to use `Debug` output for the tag, because `()` does not implement
// `Display` so we cannot specialize that.
impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
impl<Tag: fmt::Debug> fmt::Debug for Pointer<Tag> {
default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
write!(f, "{:#?}+0x{:x}[{:?}]", self.alloc_id, self.offset.bytes(), self.tag)
Expand All @@ -133,7 +129,7 @@ impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Pointer<Tag, Id> {
}
}
// Specialization for no tag
impl<Id: fmt::Debug> fmt::Debug for Pointer<(), Id> {
impl fmt::Debug for Pointer<()> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
write!(f, "{:#?}+0x{:x}", self.alloc_id, self.offset.bytes())
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_middle/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl<'tcx> ConstValue<'tcx> {
/// of a simple value or a pointer into another `Allocation`
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
#[derive(HashStable)]
pub enum Scalar<Tag = (), Id = AllocId> {
pub enum Scalar<Tag = ()> {
/// The raw bytes of a simple value.
Raw {
/// The first `size` bytes of `data` are the value.
Expand All @@ -101,15 +101,15 @@ pub enum Scalar<Tag = (), Id = AllocId> {
/// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
/// relocations, but a `Scalar` is only large enough to contain one, so we just represent the
/// relocation and its associated offset together as a `Pointer` here.
Ptr(Pointer<Tag, Id>),
Ptr(Pointer<Tag>),
}

#[cfg(target_arch = "x86_64")]
static_assert_size!(Scalar, 24);

// We want the `Debug` output to be readable as it is used by `derive(Debug)` for
// all the Miri types.
impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for Scalar<Tag, Id> {
impl<Tag: fmt::Debug> fmt::Debug for Scalar<Tag> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Scalar::Ptr(ptr) => write!(f, "{:?}", ptr),
Expand Down Expand Up @@ -542,8 +542,8 @@ impl<Tag> From<Pointer<Tag>> for Scalar<Tag> {
}

#[derive(Clone, Copy, Eq, PartialEq, RustcEncodable, RustcDecodable, HashStable, Hash)]
pub enum ScalarMaybeUndef<Tag = (), Id = AllocId> {
Scalar(Scalar<Tag, Id>),
pub enum ScalarMaybeUndef<Tag = ()> {
Scalar(Scalar<Tag>),
Undef,
}

Expand All @@ -563,7 +563,7 @@ impl<Tag> From<Pointer<Tag>> for ScalarMaybeUndef<Tag> {

// We want the `Debug` output to be readable as it is used by `derive(Debug)` for
// all the Miri types.
impl<Tag: fmt::Debug, Id: fmt::Debug> fmt::Debug for ScalarMaybeUndef<Tag, Id> {
impl<Tag: fmt::Debug> fmt::Debug for ScalarMaybeUndef<Tag> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ScalarMaybeUndef::Undef => write!(f, "<uninitialized>"),
Expand Down
36 changes: 34 additions & 2 deletions src/librustc_middle/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_hir as ast;
use rustc_hir::def_id::DefId;
use rustc_span::DUMMY_SP;
use rustc_target::spec::abi;
use std::iter;
use std::rc::Rc;
Expand Down Expand Up @@ -507,6 +508,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
a: &'tcx ty::Const<'tcx>,
b: &'tcx ty::Const<'tcx>,
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
let tcx = relation.tcx();

let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
Expand Down Expand Up @@ -561,7 +563,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
}
}

(a_val @ ConstValue::Slice { .. }, b_val @ ConstValue::Slice { .. }) => {
(ConstValue::Slice { .. }, ConstValue::Slice { .. }) => {
let a_bytes = get_slice_bytes(&tcx, a_val);
let b_bytes = get_slice_bytes(&tcx, b_val);
if a_bytes == b_bytes {
Expand All @@ -571,7 +573,37 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
}
}

// FIXME(const_generics): handle `ConstValue::ByRef`.
(ConstValue::ByRef { .. }, ConstValue::ByRef { .. }) => {
match a.ty.kind {
ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
let a_destructured = tcx.destructure_const(relation.param_env().and(a));
let b_destructured = tcx.destructure_const(relation.param_env().and(b));

// Both the variant and each field have to be equal.
if a_destructured.variant == b_destructured.variant {
for (a_field, b_field) in
a_destructured.fields.iter().zip(b_destructured.fields.iter())
{
relation.consts(a_field, b_field)?;
}

Ok(a_val)
} else {
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
}
}
// FIXME(const_generics): There are probably some `TyKind`s
// which should be handled here.
_ => {
tcx.sess.delay_span_bug(
DUMMY_SP,
&format!("unexpected consts: a: {:?}, b: {:?}", a, b),
);
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
}
}
}

_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
};

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl Error for ConstEvalErrKind {}
/// Should be called only if the error is actually going to to be reported!
pub fn error_to_const_error<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>(
ecx: &InterpCx<'mir, 'tcx, M>,
mut error: InterpErrorInfo<'tcx>,
error: InterpErrorInfo<'tcx>,
) -> ConstEvalErr<'tcx> {
error.print_backtrace();
let stacktrace = ecx.generate_stacktrace();
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_macros::HashStable;
use rustc_middle::ich::StableHashingContext;
use rustc_middle::mir;
use rustc_middle::mir::interpret::{
sign_extend, truncate, AllocId, FrameInfo, GlobalId, InterpResult, Pointer, Scalar,
sign_extend, truncate, FrameInfo, GlobalId, InterpResult, Pointer, Scalar,
};
use rustc_middle::ty::layout::{self, TyAndLayout};
use rustc_middle::ty::{
Expand Down Expand Up @@ -103,16 +103,16 @@ pub enum StackPopCleanup {

/// State of a local variable including a memoized layout
#[derive(Clone, PartialEq, Eq, HashStable)]
pub struct LocalState<'tcx, Tag = (), Id = AllocId> {
pub value: LocalValue<Tag, Id>,
pub struct LocalState<'tcx, Tag = ()> {
pub value: LocalValue<Tag>,
/// Don't modify if `Some`, this is only used to prevent computing the layout twice
#[stable_hasher(ignore)]
pub layout: Cell<Option<TyAndLayout<'tcx>>>,
}

/// Current value of a local variable
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable)] // Miri debug-prints these
pub enum LocalValue<Tag = (), Id = AllocId> {
pub enum LocalValue<Tag = ()> {
/// This local is not currently alive, and cannot be used at all.
Dead,
/// This local is alive but not yet initialized. It can be written to
Expand All @@ -125,7 +125,7 @@ pub enum LocalValue<Tag = (), Id = AllocId> {
/// This is an optimization over just always having a pointer here;
/// we can thus avoid doing an allocation when the local just stores
/// immediate values *and* never has its address taken.
Live(Operand<Tag, Id>),
Live(Operand<Tag>),
}

impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
Expand Down
16 changes: 8 additions & 8 deletions src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use rustc_target::abi::{Abi, DiscriminantKind, HasDataLayout, Integer, LayoutOf,
use rustc_target::abi::{VariantIdx, Variants};

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

/// An `Immediate` represents a single immediate self-contained Rust value.
Expand All @@ -27,9 +27,9 @@ use super::{
/// In particular, thanks to `ScalarPair`, arithmetic operations and casts can be entirely
/// defined on `Immediate`, and do not have to work with a `Place`.
#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, Hash)]
pub enum Immediate<Tag = (), Id = AllocId> {
Scalar(ScalarMaybeUndef<Tag, Id>),
ScalarPair(ScalarMaybeUndef<Tag, Id>, ScalarMaybeUndef<Tag, Id>),
pub enum Immediate<Tag = ()> {
Scalar(ScalarMaybeUndef<Tag>),
ScalarPair(ScalarMaybeUndef<Tag>, ScalarMaybeUndef<Tag>),
}

impl<Tag> From<ScalarMaybeUndef<Tag>> for Immediate<Tag> {
Expand Down Expand Up @@ -145,9 +145,9 @@ impl<'tcx, Tag> ::std::ops::Deref for ImmTy<'tcx, Tag> {
/// or still in memory. The latter is an optimization, to delay reading that chunk of
/// memory and to avoid having to store arbitrary-sized data here.
#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, Hash)]
pub enum Operand<Tag = (), Id = AllocId> {
Immediate(Immediate<Tag, Id>),
Indirect(MemPlace<Tag, Id>),
pub enum Operand<Tag = ()> {
Immediate(Immediate<Tag>),
Indirect(MemPlace<Tag>),
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
Expand Down
20 changes: 9 additions & 11 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ use super::{

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
/// Information required for the sound usage of a `MemPlace`.
pub enum MemPlaceMeta<Tag = (), Id = AllocId> {
pub enum MemPlaceMeta<Tag = ()> {
/// The unsized payload (e.g. length for slices or vtable pointer for trait objects).
Meta(Scalar<Tag, Id>),
Meta(Scalar<Tag>),
/// `Sized` types or unsized `extern type`
None,
/// The address of this place may not be taken. This protects the `MemPlace` from coming from
Expand All @@ -32,8 +32,8 @@ pub enum MemPlaceMeta<Tag = (), Id = AllocId> {
Poison,
}

impl<Tag, Id> MemPlaceMeta<Tag, Id> {
pub fn unwrap_meta(self) -> Scalar<Tag, Id> {
impl<Tag> MemPlaceMeta<Tag> {
pub fn unwrap_meta(self) -> Scalar<Tag> {
match self {
Self::Meta(s) => s,
Self::None | Self::Poison => {
Expand All @@ -47,9 +47,7 @@ impl<Tag, Id> MemPlaceMeta<Tag, Id> {
Self::None | Self::Poison => false,
}
}
}

impl<Tag> MemPlaceMeta<Tag> {
pub fn erase_tag(self) -> MemPlaceMeta<()> {
match self {
Self::Meta(s) => MemPlaceMeta::Meta(s.erase_tag()),
Expand All @@ -60,22 +58,22 @@ impl<Tag> MemPlaceMeta<Tag> {
}

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
pub struct MemPlace<Tag = (), Id = AllocId> {
pub struct MemPlace<Tag = ()> {
/// A place may have an integral pointer for ZSTs, and since it might
/// be turned back into a reference before ever being dereferenced.
/// However, it may never be undef.
pub ptr: Scalar<Tag, Id>,
pub ptr: Scalar<Tag>,
pub align: Align,
/// Metadata for unsized places. Interpretation is up to the type.
/// Must not be present for sized types, but can be missing for unsized types
/// (e.g., `extern type`).
pub meta: MemPlaceMeta<Tag, Id>,
pub meta: MemPlaceMeta<Tag>,
}

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
pub enum Place<Tag = (), Id = AllocId> {
pub enum Place<Tag = ()> {
/// A place referring to a value allocated in the `Memory` system.
Ptr(MemPlace<Tag, Id>),
Ptr(MemPlace<Tag>),

/// To support alloc-free locals, we are able to write directly to a local.
/// (Without that optimization, we'd just always be a `MemPlace`.)
Expand Down
1 change: 0 additions & 1 deletion src/librustc_trait_selection/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>(
(impl_trait_ref, impl_obligations)
}

/// See [`super::obligations_for_generics`].
pub fn predicates_for_generics<'tcx>(
cause: ObligationCause<'tcx>,
recursion_depth: usize,
Expand Down
Loading