Skip to content

Commit

Permalink
Auto merge of rust-lang#83333 - Dylan-DPC:rollup-0rdt6sz, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - rust-lang#82707 (const_evaluatable_checked: Stop eagerly erroring in `is_const_evaluatable`)
 - rust-lang#83040 (extract `ConstKind::Unevaluated` into a struct)
 - rust-lang#83280 (Fix pluralization in keyword docs)
 - rust-lang#83289 (Move some tests to more reasonable directories - 5)
 - rust-lang#83306 (Extend `proc_macro_back_compat` lint to `js-sys`)
 - rust-lang#83327 (Extend comment in `UsedLocals::visit_lhs`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 21, 2021
2 parents ed4005d + 69f6a19 commit bbf07c0
Show file tree
Hide file tree
Showing 94 changed files with 436 additions and 295 deletions.
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
};
match const_.val {
ConstKind::Value(_) => {}
ConstKind::Unevaluated(def, ref substs, promoted) => {
ConstKind::Unevaluated(unevaluated) => {
if let Err(err) =
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None)
{
all_constants_ok = false;
match err {
Expand Down Expand Up @@ -122,14 +122,14 @@ pub(crate) fn codegen_constant<'tcx>(
};
let const_val = match const_.val {
ConstKind::Value(const_val) => const_val,
ConstKind::Unevaluated(def, ref substs, promoted) if fx.tcx.is_static(def.did) => {
ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => {
assert!(substs.is_empty());
assert!(promoted.is_none());

return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx);
}
ConstKind::Unevaluated(def, ref substs, promoted) => {
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) {
ConstKind::Unevaluated(unevaluated) => {
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
Ok(const_val) => const_val,
Err(_) => {
span_bug!(constant.span, "erroneous constant not captured by required_consts");
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::ConstantKind::Val(val, _) => return Ok(val),
};
match ct.val {
ty::ConstKind::Unevaluated(def, substs, promoted) => self
ty::ConstKind::Unevaluated(ct) => self
.cx
.tcx()
.const_eval_resolve(ty::ParamEnv::reveal_all(), def, substs, promoted, None)
.const_eval_resolve(ty::ParamEnv::reveal_all(), ct, None)
.map_err(|err| {
self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
err
Expand Down
34 changes: 30 additions & 4 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -739,9 +739,8 @@ fn ident_name_compatibility_hack(

let time_macros_impl =
macro_name == sym::impl_macros && matches_prefix("time-macros-impl", "lib.rs");
if time_macros_impl
|| (macro_name == sym::arrays && matches_prefix("js-sys", "lib.rs"))
{
let js_sys = macro_name == sym::arrays && matches_prefix("js-sys", "lib.rs");
if time_macros_impl || js_sys {
let snippet = source_map.span_to_snippet(orig_span);
if snippet.as_deref() == Ok("$name") {
if time_macros_impl {
Expand All @@ -754,8 +753,35 @@ fn ident_name_compatibility_hack(
"the `time-macros-impl` crate will stop compiling in futures version of Rust. \
Please update to the latest version of the `time` crate to avoid breakage".to_string())
);
return Some((*ident, *is_raw));
}
if js_sys {
if let Some(c) = path
.components()
.flat_map(|c| c.as_os_str().to_str())
.find(|c| c.starts_with("js-sys"))
{
let mut version = c.trim_start_matches("js-sys-").split(".");
if version.next() == Some("0")
&& version.next() == Some("3")
&& version
.next()
.and_then(|c| c.parse::<u32>().ok())
.map_or(false, |v| v < 40)
{
rustc.sess.buffer_lint_with_diagnostic(
&PROC_MACRO_BACK_COMPAT,
orig_span,
ast::CRATE_NODE_ID,
"using an old version of `js-sys`",
BuiltinLintDiagnostics::ProcMacroBackCompat(
"older versions of the `js-sys` crate will stop compiling in future versions of Rust; \
please update to `js-sys` v0.3.40 or above".to_string())
);
return Some((*ident, *is_raw));
}
}
}
return Some((*ident, *is_raw));
}
}

Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
use rustc_middle::mir;
use rustc_middle::mir::interpret::EvalToConstValueResult;
use rustc_middle::traits::select;
use rustc_middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
Expand Down Expand Up @@ -1499,9 +1498,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn const_eval_resolve(
&self,
param_env: ty::ParamEnv<'tcx>,
def: ty::WithOptConstParam<DefId>,
substs: SubstsRef<'tcx>,
promoted: Option<mir::Promoted>,
ty::Unevaluated { def, substs, promoted }: ty::Unevaluated<'tcx>,
span: Option<Span>,
) -> EvalToConstValueResult<'tcx> {
let mut original_values = OriginalQueryValues::default();
Expand All @@ -1510,7 +1507,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let (param_env, substs) = canonical.value;
// The return value is the evaluated value which doesn't contain any reference to inference
// variables, thus we don't need to substitute back the original values.
self.tcx.const_eval_resolve(param_env, def, substs, promoted, span)
self.tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, span)
}

/// If `typ` is a type variable of some kind, resolve it one level
Expand Down
17 changes: 17 additions & 0 deletions compiler/rustc_middle/src/mir/abstract_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,20 @@ pub enum Node<'tcx> {
UnaryOp(mir::UnOp, NodeId),
FunctionCall(NodeId, &'tcx [NodeId]),
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
pub enum NotConstEvaluatable {
Error(rustc_errors::ErrorReported),
MentionsInfer,
MentionsParam,
}

impl From<rustc_errors::ErrorReported> for NotConstEvaluatable {
fn from(e: rustc_errors::ErrorReported) -> NotConstEvaluatable {
NotConstEvaluatable::Error(e)
}
}

TrivialTypeFoldableAndLiftImpls! {
NotConstEvaluatable,
}
10 changes: 4 additions & 6 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{ErrorHandled, EvalToConstValueResult, GlobalId};

use crate::mir;
use crate::ty::subst::{InternalSubsts, SubstsRef};
use crate::ty::subst::InternalSubsts;
use crate::ty::{self, TyCtxt};
use rustc_hir::def_id::DefId;
use rustc_span::Span;
Expand Down Expand Up @@ -35,14 +35,12 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn const_eval_resolve(
self,
param_env: ty::ParamEnv<'tcx>,
def: ty::WithOptConstParam<DefId>,
substs: SubstsRef<'tcx>,
promoted: Option<mir::Promoted>,
ct: ty::Unevaluated<'tcx>,
span: Option<Span>,
) -> EvalToConstValueResult<'tcx> {
match ty::Instance::resolve_opt_const_arg(self, param_env, def, substs) {
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
Ok(Some(instance)) => {
let cid = GlobalId { instance, promoted };
let cid = GlobalId { instance, promoted: ct.promoted };
self.const_eval_global_id(param_env, cid, span)
}
Ok(None) => Err(ErrorHandled::TooGeneric),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub mod specialization_graph;
mod structural_impls;

use crate::infer::canonical::Canonical;
use crate::mir::interpret::ErrorHandled;
use crate::mir::abstract_const::NotConstEvaluatable;
use crate::ty::subst::SubstsRef;
use crate::ty::{self, AdtKind, Ty, TyCtxt};

Expand Down Expand Up @@ -398,7 +398,7 @@ pub enum SelectionError<'tcx> {
ty::error::TypeError<'tcx>,
),
TraitNotObjectSafe(DefId),
ConstEvalFailure(ErrorHandled),
NotConstEvaluatable(NotConstEvaluatable),
Overflow,
}

Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,18 @@ impl<'tcx> Const<'tcx> {
let name = tcx.hir().name(hir_id);
ty::ConstKind::Param(ty::ParamConst::new(index, name))
}
_ => ty::ConstKind::Unevaluated(
def.to_global(),
InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
None,
),
_ => ty::ConstKind::Unevaluated(ty::Unevaluated {
def: def.to_global(),
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
promoted: None,
}),
};

tcx.mk_const(ty::Const { val, ty })
}

#[inline]
/// Interns the given value as a constant.
#[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 })
}
Expand Down
19 changes: 14 additions & 5 deletions compiler/rustc_middle/src/ty/consts/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ use rustc_macros::HashStable;
use rustc_target::abi::Size;

use super::ScalarInt;
/// An unevaluated, potentially generic, constant.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable)]
pub struct Unevaluated<'tcx> {
pub def: ty::WithOptConstParam<DefId>,
pub substs: SubstsRef<'tcx>,
pub promoted: Option<Promoted>,
}

/// Represents a constant in Rust.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
#[derive(HashStable)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable)]
pub enum ConstKind<'tcx> {
/// A const generic parameter.
Param(ty::ParamConst),
Expand All @@ -31,7 +39,7 @@ pub enum ConstKind<'tcx> {

/// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
/// variants when the code is monomorphic enough for that.
Unevaluated(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>, Option<Promoted>),
Unevaluated(Unevaluated<'tcx>),

/// Used to hold computed value.
Value(ConstValue<'tcx>),
Expand Down Expand Up @@ -102,7 +110,7 @@ impl<'tcx> ConstKind<'tcx> {
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
) -> Option<Result<ConstValue<'tcx>, ErrorReported>> {
if let ConstKind::Unevaluated(def, substs, promoted) = self {
if let ConstKind::Unevaluated(Unevaluated { def, substs, promoted }) = self {
use crate::mir::interpret::ErrorHandled;

// HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
Expand Down Expand Up @@ -132,7 +140,8 @@ impl<'tcx> ConstKind<'tcx> {
let (param_env, substs) = param_env_and_substs.into_parts();
// try to resolve e.g. associated constants to their definition on an impl, and then
// evaluate the const.
match tcx.const_eval_resolve(param_env, def, substs, promoted, None) {
match tcx.const_eval_resolve(param_env, ty::Unevaluated { def, substs, promoted }, None)
{
// NOTE(eddyb) `val` contains no lifetimes/types/consts,
// and we use the original type, so nothing from `substs`
// (which may be identity substs, see above),
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_middle/src/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,7 @@ impl FlagComputation {
fn add_const(&mut self, c: &ty::Const<'_>) {
self.add_ty(c.ty);
match c.val {
ty::ConstKind::Unevaluated(_, substs, _) => {
self.add_substs(substs);
self.add_flags(TypeFlags::HAS_CT_PROJECTION);
}
ty::ConstKind::Unevaluated(unevaluated) => self.add_unevaluated_const(unevaluated),
ty::ConstKind::Infer(infer) => {
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
match infer {
Expand All @@ -297,6 +294,11 @@ impl FlagComputation {
}
}

fn add_unevaluated_const(&mut self, ct: ty::Unevaluated<'tcx>) {
self.add_substs(ct.substs);
self.add_flags(TypeFlags::HAS_CT_PROJECTION);
}

fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
self.add_substs(projection.substs);
self.add_ty(projection.ty);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub use rustc_type_ir::*;

pub use self::binding::BindingMode;
pub use self::binding::BindingMode::*;
pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt, ValTree};
pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt, Unevaluated, ValTree};
pub use self::context::{
tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorInteriorTypeCause, GlobalCtxt,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ pub trait PrettyPrinter<'tcx>:
}

match ct.val {
ty::ConstKind::Unevaluated(def, substs, promoted) => {
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
if let Some(promoted) = promoted {
p!(print_value_path(def.did, substs));
p!(write("::{:?}", promoted));
Expand Down
24 changes: 13 additions & 11 deletions compiler/rustc_middle/src/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,24 +531,26 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
check_const_value_eq(relation, a_val, b_val, a, b)?
}

(
ty::ConstKind::Unevaluated(a_def, a_substs, None),
ty::ConstKind::Unevaluated(b_def, b_substs, None),
) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => {
tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs)))
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() =>
{
tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs)))
}

// While this is slightly incorrect, it shouldn't matter for `min_const_generics`
// and is the better alternative to waiting until `const_evaluatable_checked` can
// be stabilized.
(
ty::ConstKind::Unevaluated(a_def, a_substs, a_promoted),
ty::ConstKind::Unevaluated(b_def, b_substs, b_promoted),
) if a_def == b_def && a_promoted == b_promoted => {
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
if au.def == bu.def && au.promoted == bu.promoted =>
{
let substs =
relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
relation.relate_with_variance(ty::Variance::Invariant, au.substs, bu.substs)?;
return Ok(tcx.mk_const(ty::Const {
val: ty::ConstKind::Unevaluated(a_def, substs, a_promoted),
val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def: au.def,
substs,
promoted: au.promoted,
}),
ty: a.ty,
}));
}
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1031,8 +1031,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
match self {
ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)),
ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)),
ty::ConstKind::Unevaluated(did, substs, promoted) => {
ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted)
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
ty::ConstKind::Unevaluated(ty::Unevaluated {
def,
substs: substs.fold_with(folder),
promoted,
})
}
ty::ConstKind::Value(_)
| ty::ConstKind::Bound(..)
Expand All @@ -1045,7 +1049,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
match *self {
ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
ty::ConstKind::Param(p) => p.visit_with(visitor),
ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor),
ty::ConstKind::Unevaluated(ct) => ct.substs.visit_with(visitor),
ty::ConstKind::Value(_)
| ty::ConstKind::Bound(..)
| ty::ConstKind::Placeholder(_)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
| ty::ConstKind::Value(_)
| ty::ConstKind::Error(_) => {}

ty::ConstKind::Unevaluated(_, substs, _) => {
stack.extend(substs.iter().rev());
ty::ConstKind::Unevaluated(ct) => {
stack.extend(ct.substs.iter().rev());
}
}
}
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_mir/src/borrow_check/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,14 +316,12 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
let tcx = self.tcx();
let maybe_uneval = match constant.literal {
ConstantKind::Ty(ct) => match ct.val {
ty::ConstKind::Unevaluated(def, substs, promoted) => {
Some((def, substs, promoted))
}
ty::ConstKind::Unevaluated(uv) => Some(uv),
_ => None,
},
_ => None,
};
if let Some((def, substs, promoted)) = maybe_uneval {
if let Some(ty::Unevaluated { def, substs, promoted }) = maybe_uneval {
if let Some(promoted) = promoted {
let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
promoted: &Body<'tcx>,
Expand Down
Loading

0 comments on commit bbf07c0

Please sign in to comment.