Skip to content

Rollup of 7 pull requests #67526

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

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0bce91f
add Scalar::try_from_(u)int methods
pvdrz Dec 14, 2019
90686de
add ImmTy::try_from_(u)int methods
pvdrz Dec 14, 2019
43888e8
Refactor region error handling to be done by mirborrowckctx
mark-i-m Dec 11, 2019
94a9c62
add unreported error variant
mark-i-m Dec 17, 2019
3902e56
tidy
mark-i-m Dec 18, 2019
e5a1f48
fix outlives suggestions
mark-i-m Dec 18, 2019
5d9e74e
some more refactoring + maintain diagnostic status quo
mark-i-m Dec 18, 2019
e4379e6
make regionerrors a typedef
mark-i-m Dec 18, 2019
6903836
Remove iter_private.rs
qnighy Dec 21, 2019
309f437
Change results to options
pvdrz Dec 21, 2019
5b06025
is_reported flag
mark-i-m Dec 21, 2019
bd0ea19
add comments
mark-i-m Dec 21, 2019
a155a9b
use vec instead of smallvec
mark-i-m Dec 21, 2019
4f0dc7b
misc cleanup in match MIR building
Centril Dec 20, 2019
f5a8d1a
simplify MIR building with cfg.goto(...)
Centril Dec 20, 2019
d855782
convert hrtb error
mark-i-m Dec 21, 2019
1d9c561
minor updates to comments
mark-i-m Dec 21, 2019
c010d84
Add simpler entry points to const eval for common usages.
skinnyBat Nov 29, 2019
6878913
Document why Any is not an unsafe trait
Mark-Simulacrum Dec 22, 2019
683c4c7
Add error message if `Scalar::from_(u)int` fails
pvdrz Dec 22, 2019
a6df38e
Utilize rust-lang/rust commit hashes in toolstate
rust-highfive Dec 22, 2019
d0c1996
Rollup merge of #66877 - skinny121:const-eval-entry-points, r=oli-obk
Centril Dec 22, 2019
c200141
Rollup merge of #67241 - mark-i-m:simplify-borrow_check-3, r=matthewj…
Centril Dec 22, 2019
074329b
Rollup merge of #67299 - christianpoveda:try_immty_from_int, r=RalfJung
Centril Dec 22, 2019
c0e266e
Rollup merge of #67499 - Centril:mir-match-clean, r=matthewjasper
Centril Dec 22, 2019
e79fc97
Rollup merge of #67506 - qnighy:remove-iter-private, r=Dylan-DPC
Centril Dec 22, 2019
5a2c6d7
Rollup merge of #67519 - Mark-Simulacrum:any-unsafe, r=Centril
Centril Dec 22, 2019
17a6d4e
Rollup merge of #67525 - Mark-Simulacrum:fix-toolstate-master, r=Centril
Centril Dec 22, 2019
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
7 changes: 5 additions & 2 deletions src/ci/publish_toolstate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ printf 'https://%s:[email protected]\n' "$TOOLSTATE_REPO_ACCESS_TOKEN" \
> "$HOME/.git-credentials"
git clone --depth=1 $TOOLSTATE_REPO

GIT_COMMIT="$(git rev-parse HEAD)"
GIT_COMMIT_MSG="$(git log --format=%s -n1 HEAD)"

cd rust-toolstate
FAILURE=1
for RETRY_COUNT in 1 2 3 4 5; do
# The purpose is to publish the new "current" toolstate in the toolstate repo.
"$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" \
"$(git log --format=%s -n1 HEAD)" \
"$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$GIT_COMMIT" \
"$GIT_COMMIT_MSG" \
"$MESSAGE_FILE" \
"$TOOLSTATE_REPO_ACCESS_TOKEN"
# `git commit` failing means nothing to commit.
Expand Down
10 changes: 10 additions & 0 deletions src/libcore/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ use crate::intrinsics;
/// See the [module-level documentation][mod] for more details.
///
/// [mod]: index.html
// This trait is not unsafe, though we rely on the specifics of it's sole impl's
// `type_id` function in unsafe code (e.g., `downcast`). Normally, that would be
// a problem, but because the only impl of `Any` is a blanket implementation, no
// other code can implement `Any`.
//
// We could plausibly make this trait unsafe -- it would not cause breakage,
// since we control all the implementations -- but we choose not to as that's
// both not really necessary and may confuse users about the distinction of
// unsafe traits and unsafe methods (i.e., `type_id` would still be safe to call,
// but we would likely want to indicate as such in documentation).
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Any: 'static {
/// Gets the `TypeId` of `self`.
Expand Down
17 changes: 0 additions & 17 deletions src/libcore/iter_private.rs

This file was deleted.

4 changes: 3 additions & 1 deletion src/librustc/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ mod error;
mod value;
mod allocation;
mod pointer;
mod queries;

pub use self::error::{
InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error,
Expand All @@ -116,9 +117,10 @@ pub use self::pointer::{Pointer, PointerArithmetic, CheckInAllocMsg};

use crate::mir;
use crate::hir::def_id::DefId;
use crate::ty::{self, TyCtxt, Instance, subst::GenericArgKind};
use crate::ty::{self, TyCtxt, Instance};
use crate::ty::codec::TyDecoder;
use crate::ty::layout::{self, Size};
use crate::ty::subst::GenericArgKind;
use std::io;
use std::fmt;
use std::num::NonZeroU32;
Expand Down
89 changes: 89 additions & 0 deletions src/librustc/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use super::{ConstEvalResult, ErrorHandled, GlobalId};

use crate::mir;
use crate::hir::def_id::DefId;
use crate::ty::{self, TyCtxt};
use crate::ty::subst::{InternalSubsts, SubstsRef};
use syntax_pos::Span;


impl<'tcx> TyCtxt<'tcx> {

/// Evaluates a constant without providing any substitutions. This is useful to evaluate consts
/// that can't take any generic arguments like statics, const items or enum discriminants. If a
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
pub fn const_eval_poly(self, def_id: DefId) -> ConstEvalResult<'tcx> {
// In some situations def_id will have substitutions within scope, but they aren't allowed
// to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any og them are
// encountered.
let substs = InternalSubsts::identity_for_item(self, def_id);
let instance = ty::Instance::new(def_id, substs);
let cid = GlobalId {
instance,
promoted: None,
};
let param_env = self.param_env(def_id);
self.const_eval_validated(param_env.and(cid))
}

/// Resolves and evaluates a constant.
///
/// The constant can be located on a trait like `<A as B>::C`, in which case the given
/// substitutions and environment are used to resolve the constant. Alternatively if the
/// constant has generic parameters in scope the substitutions are used to evaluate the value of
/// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
/// constant `bar::<T>()` requires a substitution for `T`, if the substitution for `T` is still
/// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
/// returned.
pub fn const_eval_resolve(
self,
param_env: ty::ParamEnv<'tcx>,
def_id: DefId,
substs: SubstsRef<'tcx>,
span: Option<Span>
) -> ConstEvalResult<'tcx> {
let instance = ty::Instance::resolve(
self,
param_env,
def_id,
substs,
);
if let Some(instance) = instance {
self.const_eval_instance(param_env, instance, span)
} else {
Err(ErrorHandled::TooGeneric)
}
}

pub fn const_eval_instance(
self,
param_env: ty::ParamEnv<'tcx>,
instance: ty::Instance<'tcx>,
span: Option<Span>
) -> ConstEvalResult<'tcx> {
let cid = GlobalId {
instance,
promoted: None,
};
if let Some(span) = span {
self.at(span).const_eval_validated(param_env.and(cid))
} else {
self.const_eval_validated(param_env.and(cid))
}
}

/// Evaluate a promoted constant.
pub fn const_eval_promoted(
self,
instance: ty::Instance<'tcx>,
promoted: mir::Promoted
) -> ConstEvalResult<'tcx> {
let cid = GlobalId {
instance,
promoted: Some(promoted),
};
let param_env = ty::ParamEnv::reveal_all();
self.const_eval_validated(param_env.and(cid))
}
}
38 changes: 27 additions & 11 deletions src/librustc/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,22 @@ impl<'tcx, Tag> Scalar<Tag> {
Scalar::Raw { data: c as u128, size: 4 }
}

#[inline]
pub fn try_from_uint(i: impl Into<u128>, size: Size) -> Option<Self> {
let i = i.into();
if truncate(i, size) == i {
Some(Scalar::Raw { data: i, size: size.bytes() as u8 })
} else {
None
}
}

#[inline]
pub fn from_uint(i: impl Into<u128>, size: Size) -> Self {
let i = i.into();
assert_eq!(
truncate(i, size), i,
"Unsigned value {:#x} does not fit in {} bits", i, size.bits()
);
Scalar::Raw { data: i, size: size.bytes() as u8 }
Self::try_from_uint(i, size).unwrap_or_else(|| {
bug!("Unsigned value {:#x} does not fit in {} bits", i, size.bits())
})
}

#[inline]
Expand All @@ -267,15 +275,23 @@ impl<'tcx, Tag> Scalar<Tag> {
}

#[inline]
pub fn from_int(i: impl Into<i128>, size: Size) -> Self {
pub fn try_from_int(i: impl Into<i128>, size: Size) -> Option<Self> {
let i = i.into();
// `into` performed sign extension, we have to truncate
let truncated = truncate(i as u128, size);
assert_eq!(
sign_extend(truncated, size) as i128, i,
"Signed value {:#x} does not fit in {} bits", i, size.bits()
);
Scalar::Raw { data: truncated, size: size.bytes() as u8 }
if sign_extend(truncated, size) as i128 == i {
Some(Scalar::Raw { data: truncated, size: size.bytes() as u8 })
} else {
None
}
}

#[inline]
pub fn from_int(i: impl Into<i128>, size: Size) -> Self {
let i = i.into();
Self::try_from_int(i, size).unwrap_or_else(|| {
bug!("Signed value {:#x} does not fit in {} bits", i, size.bits())
})
}

#[inline]
Expand Down
11 changes: 9 additions & 2 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ rustc_queries! {
///
/// **Do not use this** outside const eval. Const eval uses this to break query cycles
/// during validation. Please add a comment to every use site explaining why using
/// `const_eval` isn't sufficient.
/// `const_eval_validated` isn't sufficient. The returned constant also isn't in a suitable
/// form to be used outside of const eval.
query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-> ConstEvalRawResult<'tcx> {
no_force
Expand All @@ -460,7 +461,13 @@ rustc_queries! {

/// Results of evaluating const items or constants embedded in
/// other items (such as enum variant explicit discriminants).
query const_eval(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
///
/// In contrast to `const_eval_raw` this performs some validation on the constant, and
/// returns a proper constant that is usable by the rest of the compiler.
///
/// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`,
/// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_promoted`.
query const_eval_validated(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-> ConstEvalResult<'tcx> {
no_force
desc { |tcx|
Expand Down
29 changes: 7 additions & 22 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::infer::{InferCtxt, ShallowResolver};
use crate::mir::interpret::{GlobalId, ErrorHandled};
use crate::ty::{self, Ty, TypeFoldable, ToPolyTraitRef};
use crate::ty::error::ExpectedFound;
use rustc_data_structures::obligation_forest::{DoCompleted, Error, ForestObligation};
Expand Down Expand Up @@ -501,27 +500,13 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
ProcessResult::Unchanged
} else {
if !substs.has_local_value() {
let instance = ty::Instance::resolve(
self.selcx.tcx(),
obligation.param_env,
def_id,
substs,
);
if let Some(instance) = instance {
let cid = GlobalId {
instance,
promoted: None,
};
match self.selcx.tcx().at(obligation.cause.span)
.const_eval(obligation.param_env.and(cid)) {
Ok(_) => ProcessResult::Changed(vec![]),
Err(err) => ProcessResult::Error(
CodeSelectionError(ConstEvalFailure(err)))
}
} else {
ProcessResult::Error(CodeSelectionError(
ConstEvalFailure(ErrorHandled::TooGeneric)
))
match self.selcx.tcx().const_eval_resolve(obligation.param_env,
def_id,
substs,
Some(obligation.cause.span)) {
Ok(_) => ProcessResult::Changed(vec![]),
Err(err) => ProcessResult::Error(
CodeSelectionError(ConstEvalFailure(err)))
}
} else {
pending_obligation.stalled_on =
Expand Down
22 changes: 6 additions & 16 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ use crate::dep_graph::{DepKind, DepNodeIndex};
use crate::hir::def_id::DefId;
use crate::infer::{CombinedSnapshot, InferCtxt, InferOk, PlaceholderMap, TypeFreshener};
use crate::middle::lang_items;
use crate::mir::interpret::GlobalId;
use crate::ty::fast_reject;
use crate::ty::relate::TypeRelation;
use crate::ty::subst::{Subst, SubstsRef};
Expand Down Expand Up @@ -820,22 +819,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}

ty::Predicate::ConstEvaluatable(def_id, substs) => {
let tcx = self.tcx();
if !(obligation.param_env, substs).has_local_value() {
let param_env = obligation.param_env;
let instance =
ty::Instance::resolve(tcx, param_env, def_id, substs);
if let Some(instance) = instance {
let cid = GlobalId {
instance,
promoted: None,
};
match self.tcx().const_eval(param_env.and(cid)) {
Ok(_) => Ok(EvaluatedToOk),
Err(_) => Ok(EvaluatedToErr),
}
} else {
Ok(EvaluatedToErr)
match self.tcx().const_eval_resolve(obligation.param_env,
def_id,
substs,
None) {
Ok(_) => Ok(EvaluatedToOk),
Err(_) => Ok(EvaluatedToErr),
}
} else {
// Inference variables still left in param_env or substs.
Expand Down
10 changes: 2 additions & 8 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::middle::cstore::CrateStoreDyn;
use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
use crate::mir::ReadOnlyBodyAndCache;
use crate::mir::interpret::{GlobalId, ErrorHandled};
use crate::mir::interpret::ErrorHandled;
use crate::mir::GeneratorLayout;
use crate::session::CrateDisambiguator;
use crate::traits::{self, Reveal};
Expand Down Expand Up @@ -2344,13 +2344,7 @@ impl<'tcx> AdtDef {
pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
let param_env = tcx.param_env(expr_did);
let repr_type = self.repr.discr_type();
let substs = InternalSubsts::identity_for_item(tcx, expr_did);
let instance = ty::Instance::new(expr_did, substs);
let cid = GlobalId {
instance,
promoted: None
};
match tcx.const_eval(param_env.and(cid)) {
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) {
Expand Down
12 changes: 4 additions & 8 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::ty::{self, AdtDef, Discr, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFolda
use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
use crate::ty::layout::VariantIdx;
use crate::util::captures::Captures;
use crate::mir::interpret::{Scalar, GlobalId};
use crate::mir::interpret::Scalar;

use polonius_engine::Atom;
use rustc_index::vec::Idx;
Expand Down Expand Up @@ -2340,13 +2340,9 @@ impl<'tcx> Const<'tcx> {

let (param_env, substs) = param_env_and_substs.into_parts();

// try to resolve e.g. associated constants to their definition on an impl
let instance = ty::Instance::resolve(tcx, param_env, did, substs)?;
let gid = GlobalId {
instance,
promoted: None,
};
tcx.const_eval(param_env.and(gid)).ok()
// 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, None).ok()
};

match self.val {
Expand Down
10 changes: 2 additions & 8 deletions src/librustc_codegen_llvm/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::value::Value;
use libc::c_uint;
use rustc::hir::def_id::DefId;
use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint,
Pointer, ErrorHandled, GlobalId};
Pointer, ErrorHandled};
use rustc::mir::mono::MonoItem;
use rustc::hir::Node;
use rustc_target::abi::HasDataLayout;
Expand Down Expand Up @@ -81,13 +81,7 @@ pub fn codegen_static_initializer(
cx: &CodegenCx<'ll, 'tcx>,
def_id: DefId,
) -> Result<(&'ll Value, &'tcx Allocation), ErrorHandled> {
let instance = ty::Instance::mono(cx.tcx, def_id);
let cid = GlobalId {
instance,
promoted: None,
};
let param_env = ty::ParamEnv::reveal_all();
let static_ = cx.tcx.const_eval(param_env.and(cid))?;
let static_ = cx.tcx.const_eval_poly(def_id)?;

let alloc = match static_.val {
ty::ConstKind::Value(ConstValue::ByRef {
Expand Down
Loading