Skip to content

Commit

Permalink
Auto merge of #69262 - Dylan-DPC:rollup-m6dt9cn, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - #69181 (Change const eval to just return the value )
 - #69192 (Add more regression tests)
 - #69200 (Fix printing of `Yield` terminator)
 - #69205 (Allow whitespaces in revision flags)
 - #69233 (Clean up E0310 explanation)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Feb 18, 2020
2 parents b0d5813 + 210b181 commit e620d0f
Show file tree
Hide file tree
Showing 37 changed files with 358 additions and 137 deletions.
3 changes: 2 additions & 1 deletion src/librustc/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::{CheckInAllocMsg, Pointer, RawConst, ScalarMaybeUndef};

use crate::hir::map::definitions::DefPathData;
use crate::mir;
use crate::mir::interpret::ConstValue;
use crate::ty::layout::{Align, LayoutError, Size};
use crate::ty::query::TyCtxtAt;
use crate::ty::{self, layout, Ty};
Expand Down Expand Up @@ -40,7 +41,7 @@ CloneTypeFoldableImpls! {
}

pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
pub type ConstEvalResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;

#[derive(Debug)]
pub struct ConstEvalErr<'tcx> {
Expand Down
38 changes: 37 additions & 1 deletion src/librustc/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::fmt;

use crate::ty::{
layout::{HasDataLayout, Size},
Ty,
ParamEnv, Ty, TyCtxt,
};

use super::{sign_extend, truncate, AllocId, Allocation, InterpResult, Pointer, PointerArithmetic};
Expand Down Expand Up @@ -66,6 +66,32 @@ impl<'tcx> ConstValue<'tcx> {
ConstValue::Scalar(val) => Some(val),
}
}

pub fn try_to_bits(&self, size: Size) -> Option<u128> {
self.try_to_scalar()?.to_bits(size).ok()
}

pub fn try_to_bits_for_ty(
&self,
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> Option<u128> {
let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
self.try_to_bits(size)
}

pub fn from_bool(b: bool) -> Self {
ConstValue::Scalar(Scalar::from_bool(b))
}

pub fn from_u64(i: u64) -> Self {
ConstValue::Scalar(Scalar::from_u64(i))
}

pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self {
ConstValue::Scalar(Scalar::from_machine_usize(i, cx))
}
}

/// A `Scalar` represents an immediate, primitive value existing outside of a
Expand Down Expand Up @@ -287,6 +313,11 @@ impl<'tcx, Tag> Scalar<Tag> {
Scalar::Raw { data: i as u128, size: 8 }
}

#[inline]
pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self {
Self::from_uint(i, cx.data_layout().pointer_size)
}

#[inline]
pub fn try_from_int(i: impl Into<i128>, size: Size) -> Option<Self> {
let i = i.into();
Expand All @@ -306,6 +337,11 @@ impl<'tcx, Tag> Scalar<Tag> {
.unwrap_or_else(|| bug!("Signed value {:#x} does not fit in {} bits", i, size.bits()))
}

#[inline]
pub fn from_machine_isize(i: i64, cx: &impl HasDataLayout) -> Self {
Self::from_int(i, cx.data_layout().pointer_size)
}

#[inline]
pub fn from_f32(f: Single) -> Self {
// We trust apfloat to give us properly truncated data.
Expand Down
16 changes: 8 additions & 8 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1468,21 +1468,21 @@ impl<'tcx> TerminatorKind<'tcx> {
/// successors, which may be rendered differently between the text and the graphviz format.
pub fn fmt_head<W: Write>(&self, fmt: &mut W) -> fmt::Result {
use self::TerminatorKind::*;
match *self {
match self {
Goto { .. } => write!(fmt, "goto"),
SwitchInt { discr: ref place, .. } => write!(fmt, "switchInt({:?})", place),
SwitchInt { discr, .. } => write!(fmt, "switchInt({:?})", discr),
Return => write!(fmt, "return"),
GeneratorDrop => write!(fmt, "generator_drop"),
Resume => write!(fmt, "resume"),
Abort => write!(fmt, "abort"),
Yield { ref value, .. } => write!(fmt, "_1 = suspend({:?})", value),
Yield { value, resume_arg, .. } => write!(fmt, "{:?} = yield({:?})", resume_arg, value),
Unreachable => write!(fmt, "unreachable"),
Drop { ref location, .. } => write!(fmt, "drop({:?})", location),
DropAndReplace { ref location, ref value, .. } => {
Drop { location, .. } => write!(fmt, "drop({:?})", location),
DropAndReplace { location, value, .. } => {
write!(fmt, "replace({:?} <- {:?})", location, value)
}
Call { ref func, ref args, ref destination, .. } => {
if let Some((ref destination, _)) = *destination {
Call { func, args, destination, .. } => {
if let Some((destination, _)) = destination {
write!(fmt, "{:?} = ", destination)?;
}
write!(fmt, "{:?}(", func)?;
Expand All @@ -1494,7 +1494,7 @@ impl<'tcx> TerminatorKind<'tcx> {
}
write!(fmt, ")")
}
Assert { ref cond, expected, ref msg, .. } => {
Assert { cond, expected, msg, .. } => {
write!(fmt, "assert(")?;
if !expected {
write!(fmt, "!")?;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ rustc_queries! {
/// Extracts a field of a (variant of a) const.
query const_field(
key: ty::ParamEnvAnd<'tcx, (&'tcx ty::Const<'tcx>, mir::Field)>
) -> &'tcx ty::Const<'tcx> {
) -> ConstValue<'tcx> {
no_force
desc { "extract field of const" }
}
Expand All @@ -533,7 +533,7 @@ rustc_queries! {
desc { "destructure constant" }
}

query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> &'tcx ty::Const<'tcx> {
query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> {
no_force
desc { "get a &core::panic::Location referring to a span" }
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2388,10 +2388,10 @@ impl<'tcx> AdtDef {
let repr_type = self.repr.discr_type();
match tcx.const_eval_poly(expr_did) {
Ok(val) => {
// FIXME: Find the right type and use it instead of `val.ty` here
if let Some(b) = val.try_eval_bits(tcx, param_env, val.ty) {
let ty = repr_type.to_ty(tcx);
if let Some(b) = val.try_to_bits_for_ty(tcx, param_env, ty) {
trace!("discriminants: {} ({:?})", b, repr_type);
Some(Discr { val: b, ty: val.ty })
Some(Discr { val: b, ty })
} else {
info!("invalid enum discriminant: {:#?}", val);
crate::mir::interpret::struct_error(
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLife
use crate::middle::stability::{self, DeprecationEntry};
use crate::mir;
use crate::mir::interpret::GlobalId;
use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult};
use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult, ConstValue};
use crate::mir::interpret::{LitToConstError, LitToConstInput};
use crate::mir::mono::CodegenUnit;
use crate::session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
Expand Down
11 changes: 9 additions & 2 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2417,9 +2417,14 @@ pub struct Const<'tcx> {
static_assert_size!(Const<'_>, 48);

impl<'tcx> Const<'tcx> {
#[inline]
pub fn from_value(tcx: TyCtxt<'tcx>, val: ConstValue<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
tcx.mk_const(Self { val: ConstKind::Value(val), ty })
}

#[inline]
pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> &'tcx Self {
tcx.mk_const(Self { val: ConstKind::Value(ConstValue::Scalar(val)), ty })
Self::from_value(tcx, ConstValue::Scalar(val), ty)
}

#[inline]
Expand Down Expand Up @@ -2473,7 +2478,9 @@ impl<'tcx> Const<'tcx> {

// try to resolve e.g. associated constants to their definition on an impl, and then
// evaluate the const.
tcx.const_eval_resolve(param_env, did, substs, promoted, None).ok()
tcx.const_eval_resolve(param_env, did, substs, promoted, None)
.ok()
.map(|val| Const::from_value(tcx, val, self.ty))
};

match self.val {
Expand Down
8 changes: 3 additions & 5 deletions src/librustc_codegen_llvm/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,9 @@ pub fn codegen_static_initializer(
cx: &CodegenCx<'ll, 'tcx>,
def_id: DefId,
) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> {
let static_ = cx.tcx.const_eval_poly(def_id)?;

let alloc = match static_.val {
ty::ConstKind::Value(ConstValue::ByRef { alloc, offset }) if offset.bytes() == 0 => alloc,
_ => bug!("static const eval returned {:#?}", static_),
let alloc = match cx.tcx.const_eval_poly(def_id)? {
ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => alloc,
val => bug!("static const eval returned {:#?}", val),
};
Ok((const_alloc_to_llvm(cx, alloc), alloc))
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
.tcx
.const_eval_instance(ty::ParamEnv::reveal_all(), instance, None)
.unwrap();
OperandRef::from_const(self, ty_name).immediate_or_packed_pair(self)
OperandRef::from_const(self, ty_name, ret_ty).immediate_or_packed_pair(self)
}
"init" => {
let ty = substs.type_at(0);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
caller.line as u32,
caller.col_display as u32 + 1,
));
OperandRef::from_const(bx, const_loc)
OperandRef::from_const(bx, const_loc, bx.tcx().caller_location_ty())
})
}

Expand Down
30 changes: 20 additions & 10 deletions src/librustc_codegen_ssa/mir/constant.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::mir::operand::OperandRef;
use crate::traits::*;
use rustc::mir;
use rustc::mir::interpret::ErrorHandled;
use rustc::mir::interpret::{ConstValue, ErrorHandled};
use rustc::ty::layout::{self, HasTyCtxt};
use rustc::ty::{self, Ty};
use rustc_index::vec::Idx;
Expand Down Expand Up @@ -30,15 +30,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
_ => {
let val = self.eval_mir_constant(constant)?;
Ok(OperandRef::from_const(bx, val))
let ty = self.monomorphize(&constant.literal.ty);
Ok(OperandRef::from_const(bx, val.clone(), ty))
}
}
}

pub fn eval_mir_constant(
&mut self,
constant: &mir::Constant<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, ErrorHandled> {
) -> Result<ConstValue<'tcx>, ErrorHandled> {
match constant.literal.val {
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
let substs = self.monomorphize(&substs);
Expand All @@ -55,7 +56,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
err
})
}
_ => Ok(self.monomorphize(&constant.literal)),
ty::ConstKind::Value(value) => Ok(value),
_ => {
let const_ = self.monomorphize(&constant.literal);
if let ty::ConstKind::Value(value) = const_.val {
Ok(value)
} else {
span_bug!(constant.span, "encountered bad ConstKind in codegen: {:?}", const_);
}
}
}
}

Expand All @@ -65,21 +74,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx: &Bx,
span: Span,
ty: Ty<'tcx>,
constant: Result<&'tcx ty::Const<'tcx>, ErrorHandled>,
constant: Result<ConstValue<'tcx>, ErrorHandled>,
) -> (Bx::Value, Ty<'tcx>) {
constant
.map(|c| {
let field_ty = c.ty.builtin_index().unwrap();
let fields = match c.ty.kind {
.map(|val| {
let field_ty = ty.builtin_index().unwrap();
let fields = match ty.kind {
ty::Array(_, n) => n.eval_usize(bx.tcx(), ty::ParamEnv::reveal_all()),
_ => bug!("invalid simd shuffle type: {}", c.ty),
_ => bug!("invalid simd shuffle type: {}", ty),
};
let c = ty::Const::from_value(bx.tcx(), val, ty);
let values: Vec<_> = (0..fields)
.map(|field| {
let field = bx.tcx().const_field(
ty::ParamEnv::reveal_all().and((&c, mir::Field::new(field as usize))),
);
if let Some(prim) = field.val.try_to_scalar() {
if let Some(prim) = field.try_to_scalar() {
let layout = bx.layout_of(field_ty);
let scalar = match layout.abi {
layout::Abi::Scalar(ref x) => x,
Expand Down
14 changes: 5 additions & 9 deletions src/librustc_codegen_ssa/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::MemFlags;

use rustc::mir;
use rustc::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
use rustc::ty;
use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
use rustc::ty::Ty;

use std::fmt;

Expand Down Expand Up @@ -66,20 +66,16 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {

pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
val: &'tcx ty::Const<'tcx>,
val: ConstValue<'tcx>,
ty: Ty<'tcx>,
) -> Self {
let layout = bx.layout_of(val.ty);
let layout = bx.layout_of(ty);

if layout.is_zst() {
return OperandRef::new_zst(bx, layout);
}

let val_val = match val.val {
ty::ConstKind::Value(val_val) => val_val,
_ => bug!("encountered bad ConstKind in codegen"),
};

let val = match val_val {
let val = match val {
ConstValue::Scalar(x) => {
let scalar = match layout.abi {
layout::Abi::Scalar(ref x) => x,
Expand Down
13 changes: 9 additions & 4 deletions src/librustc_error_codes/error_codes/E0310.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Types in type definitions have lifetimes associated with them that represent
how long the data stored within them is guaranteed to be live. This lifetime
must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error.
A parameter type is missing a lifetime constraint or has a lifetime that
does not live long enough.

Erroneous code example:

```compile_fail,E0310
// This won't compile because T is not constrained to the static lifetime
Expand All @@ -11,6 +11,11 @@ struct Foo<T> {
}
```

Type parameters in type definitions have lifetimes associated with them that
represent how long the data stored within them is guaranteed to live. This
lifetime must be as long as the data needs to be alive, and missing the
constraint that denotes this will cause this error.

This will compile, because it has the constraint on the type parameter:

```
Expand Down
15 changes: 5 additions & 10 deletions src/librustc_mir/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(crate) fn const_field<'tcx>(
variant: Option<VariantIdx>,
field: mir::Field,
value: &'tcx ty::Const<'tcx>,
) -> &'tcx ty::Const<'tcx> {
) -> ConstValue<'tcx> {
trace!("const_field: {:?}, {:?}", field, value);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
// get the operand again
Expand All @@ -46,19 +46,13 @@ pub(crate) fn const_field<'tcx>(
pub(crate) fn const_caller_location<'tcx>(
tcx: TyCtxt<'tcx>,
(file, line, col): (Symbol, u32, u32),
) -> &'tcx ty::Const<'tcx> {
) -> ConstValue<'tcx> {
trace!("const_caller_location: {}:{}:{}", file, line, col);
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), false);

let loc_ty = tcx.caller_location_ty();
let loc_place = ecx.alloc_caller_location(file, line, col);
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, loc_place, false).unwrap();
let loc_const = ty::Const {
ty: loc_ty,
val: ty::ConstKind::Value(ConstValue::Scalar(loc_place.ptr.into())),
};

tcx.mk_const(loc_const)
ConstValue::Scalar(loc_place.ptr.into())
}

// this function uses `unwrap` copiously, because an already validated constant
Expand All @@ -84,7 +78,8 @@ pub(crate) fn destructure_const<'tcx>(
let down = ecx.operand_downcast(op, variant).unwrap();
let fields_iter = (0..field_count).map(|i| {
let field_op = ecx.operand_field(down, i).unwrap();
op_to_const(&ecx, field_op)
let val = op_to_const(&ecx, field_op);
ty::Const::from_value(tcx, val, field_op.layout.ty)
});
let fields = tcx.arena.alloc_from_iter(fields_iter);

Expand Down
Loading

0 comments on commit e620d0f

Please sign in to comment.