Skip to content

Commit

Permalink
Auto merge of #67532 - Centril:rollup-3duj42d, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - #66877 (Add simpler entry points to const eval for common usages.)
 - #67299 (Add `ImmTy::try_from_(u)int` methods)
 - #67487 (Rustdoc mutability removal)
 - #67499 (Misc MIR building cleanups)
 - #67506 (Remove iter_private.rs)
 - #67508 (Fix typo in path parser name)
 - #67519 (Document why Any is not an unsafe trait)
 - #67525 (Utilize rust-lang/rust commit hashes in toolstate)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Dec 22, 2019
2 parents 0d2817a + 9c5b73e commit 9b98af8
Show file tree
Hide file tree
Showing 41 changed files with 320 additions and 428 deletions.
7 changes: 5 additions & 2 deletions src/ci/publish_toolstate.sh
Expand Up @@ -14,12 +14,15 @@ printf 'https://%s:x-oauth-basic@github.com\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
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
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
@@ -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
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
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
@@ -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
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
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
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
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

0 comments on commit 9b98af8

Please sign in to comment.