};
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 {
};
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");
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
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 {
"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));
}
}
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};
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();
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
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,
+}
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;
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),
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};
ty::error::TypeError<'tcx>,
),
TraitNotObjectSafe(DefId),
- ConstEvalFailure(ErrorHandled),
+ NotConstEvaluatable(NotConstEvaluatable),
Overflow,
}
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 })
}
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),
/// 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>),
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`
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),
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 {
}
}
+ 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);
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,
}
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));
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,
}));
}
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(..)
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(_)
| 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());
}
}
}
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>,
match val.val {
ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric),
ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)),
- ty::ConstKind::Unevaluated(def, substs, promoted) => {
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
let instance = self.resolve(def, substs)?;
Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into())
}
match substituted_constant.val {
ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output),
- ty::ConstKind::Unevaluated(def, substs, promoted) => {
- match self.tcx.const_eval_resolve(param_env, def, substs, promoted, None) {
+ ty::ConstKind::Unevaluated(unevaluated) => {
+ match self.tcx.const_eval_resolve(param_env, unevaluated, None) {
Ok(val) => collect_const_value(self.tcx, val, self.output),
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
Err(ErrorHandled::TooGeneric) => span_bug!(
self.unused_parameters.clear(param.index);
ControlFlow::CONTINUE
}
- ty::ConstKind::Unevaluated(def, _, Some(p))
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted: Some(p)})
// Avoid considering `T` unused when constants are of the form:
// `<Self as Foo<T>>::foo::promoted[p]`
if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self =>
self.visit_body(&promoted[p]);
ControlFlow::CONTINUE
}
- ty::ConstKind::Unevaluated(def, unevaluated_substs, None)
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None })
if self.tcx.def_kind(def.did) == DefKind::AnonConst =>
{
- self.visit_child_body(def.did, unevaluated_substs);
+ self.visit_child_body(def.did, substs);
ControlFlow::CONTINUE
}
_ => c.super_visit_with(self),
// Check the qualifs of the value of `const` items.
if let Some(ct) = constant.literal.const_for_ty() {
- if let ty::ConstKind::Unevaluated(def, _, promoted) = ct.val {
+ if let ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) = ct.val {
assert!(promoted.is_none());
// Don't peek inside trait associated constants.
if cx.tcx.trait_of_item(def.did).is_none() {
let lint_only = match c.literal {
ConstantKind::Ty(ct) => match ct.val {
// Promoteds must lint and not error as the user didn't ask for them
- ConstKind::Unevaluated(_, _, Some(_)) => true,
+ ConstKind::Unevaluated(ty::Unevaluated {
+ def: _,
+ substs: _,
+ promoted: Some(_),
+ }) => true,
// Out of backwards compatibility we cannot report hard errors in unused
// generic functions using associated constants of the generic parameters.
_ => c.literal.needs_subst(),
caller_body.required_consts.extend(
callee_body.required_consts.iter().copied().filter(|&ct| {
match ct.literal.const_for_ty() {
- Some(ct) => matches!(ct.val, ConstKind::Unevaluated(_, _, _)),
+ Some(ct) => matches!(ct.val, ConstKind::Unevaluated(_)),
None => true,
}
}),
literal: tcx
.mk_const(ty::Const {
ty,
- val: ty::ConstKind::Unevaluated(
+ val: ty::ConstKind::Unevaluated(ty::Unevaluated {
def,
- InternalSubsts::for_item(tcx, def.did, |param, _| {
+ substs: InternalSubsts::for_item(tcx, def.did, |param, _| {
if let ty::GenericParamDefKind::Lifetime = param.kind {
tcx.lifetimes.re_erased.into()
} else {
tcx.mk_param_from_def(param)
}
}),
- Some(promoted_id),
- ),
+ promoted: Some(promoted_id),
+ }),
})
.into(),
}))
impl<'a, 'tcx> Visitor<'tcx> for RequiredConstsVisitor<'a, 'tcx> {
fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
if let Some(ct) = constant.literal.const_for_ty() {
- if let ConstKind::Unevaluated(_, _, _) = ct.val {
+ if let ConstKind::Unevaluated(_) = ct.val {
self.required_consts.push(*constant);
}
}
// A use, not a definition.
self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), location);
} else {
- // A definition. Although, it still might use other locals for indexing.
+ // A definition. The base local itself is not visited, so this occurrence is not counted
+ // toward its use count. There might be other locals still, used in an indexing
+ // projection.
self.super_projection(
place.as_ref(),
PlaceContext::MutatingUse(MutatingUseContext::Projection),
// and not the beginning of discriminants (which is always `0`)
let substs = InternalSubsts::identity_for_item(self.tcx(), did);
let lhs = mk_const(self.tcx().mk_const(ty::Const {
- val: ty::ConstKind::Unevaluated(
- ty::WithOptConstParam::unknown(did),
+ val: ty::ConstKind::Unevaluated(ty::Unevaluated {
+ def: ty::WithOptConstParam::unknown(did),
substs,
- None,
- ),
+ promoted: None,
+ }),
ty: var_ty,
}));
let bin =
debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
ExprKind::Literal {
literal: self.tcx.mk_const(ty::Const {
- val: ty::ConstKind::Unevaluated(
- ty::WithOptConstParam::unknown(def_id),
+ val: ty::ConstKind::Unevaluated(ty::Unevaluated {
+ def: ty::WithOptConstParam::unknown(def_id),
substs,
- None,
- ),
+ promoted: None,
+ }),
ty: self.typeck_results().node_type(expr.hir_id),
}),
user_ty,
}
ty::PredicateKind::ConstEquate(c1, c2) => {
let evaluate = |c: &'tcx ty::Const<'tcx>| {
- if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
+ if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
match select.infcx().const_eval_resolve(
obligation.param_env,
- def,
- substs,
- promoted,
+ unevaluated,
Some(obligation.cause.span),
) {
Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty)),
use rustc_index::bit_set::BitSet;
use rustc_index::vec::IndexVec;
use rustc_infer::infer::InferCtxt;
-use rustc_middle::mir::abstract_const::{Node, NodeId};
+use rustc_middle::mir::abstract_const::{Node, NodeId, NotConstEvaluatable};
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind};
use rustc_middle::ty::subst::{Subst, SubstsRef};
substs: SubstsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>,
span: Span,
-) -> Result<(), ErrorHandled> {
+) -> Result<(), NotConstEvaluatable> {
debug!("is_const_evaluatable({:?}, {:?})", def, substs);
if infcx.tcx.features().const_evaluatable_checked {
let tcx = infcx.tcx;
match failure_kind {
FailureKind::MentionsInfer => {
- return Err(ErrorHandled::TooGeneric);
+ return Err(NotConstEvaluatable::MentionsInfer);
}
FailureKind::MentionsParam => {
- // FIXME(const_evaluatable_checked): Better error message.
- let mut err =
- infcx.tcx.sess.struct_span_err(span, "unconstrained generic constant");
- let const_span = tcx.def_span(def.did);
- // FIXME(const_evaluatable_checked): Update this suggestion once
- // explicit const evaluatable bounds are implemented.
- if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(const_span)
- {
- err.span_help(
- tcx.def_span(def.did),
- &format!("try adding a `where` bound using this expression: `where [u8; {}]: Sized`", snippet),
- );
- } else {
- err.span_help(
- const_span,
- "consider adding a `where` bound for this expression",
- );
- }
- err.emit();
- return Err(ErrorHandled::Reported(ErrorReported));
+ return Err(NotConstEvaluatable::MentionsParam);
}
FailureKind::Concrete => {
// Dealt with below by the same code which handles this
// and hopefully soon change this to an error.
//
// See #74595 for more details about this.
- let concrete = infcx.const_eval_resolve(param_env, def, substs, None, Some(span));
+ let concrete = infcx.const_eval_resolve(
+ param_env,
+ ty::Unevaluated { def, substs, promoted: None },
+ Some(span),
+ );
if concrete.is_ok() && substs.has_param_types_or_consts() {
match infcx.tcx.def_kind(def.did) {
debug!(?concrete, "is_const_evaluatable");
match concrete {
- Err(ErrorHandled::TooGeneric) if !substs.has_infer_types_or_consts() => {
- // FIXME(const_evaluatable_checked): We really should move
- // emitting this error message to fulfill instead. For
- // now this is easier.
- //
- // This is not a problem without `const_evaluatable_checked` as
- // all `ConstEvaluatable` predicates have to be fulfilled for compilation
- // to succeed.
- //
- // @lcnr: We already emit an error for things like
- // `fn test<const N: usize>() -> [0 - N]` eagerly here,
- // so until we fix this I don't really care.
-
- let mut err = infcx
- .tcx
- .sess
- .struct_span_err(span, "constant expression depends on a generic parameter");
- // FIXME(const_generics): we should suggest to the user how they can resolve this
- // issue. However, this is currently not actually possible
- // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083).
- //
- // Note that with `feature(const_evaluatable_checked)` this case should not
- // be reachable.
- err.note("this may fail depending on what value the parameter takes");
- err.emit();
- Err(ErrorHandled::Reported(ErrorReported))
+ Err(ErrorHandled::TooGeneric) => Err(match substs.has_infer_types_or_consts() {
+ true => NotConstEvaluatable::MentionsInfer,
+ false => NotConstEvaluatable::MentionsParam,
+ }),
+ Err(ErrorHandled::Linted) => {
+ infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
+ Err(NotConstEvaluatable::Error(ErrorReported))
}
- c => c.map(drop),
+ Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
+ Ok(_) => Ok(()),
}
}
ct: &ty::Const<'tcx>,
) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
match ct.val {
- ty::ConstKind::Unevaluated(def, substs, None) => AbstractConst::new(tcx, def, substs),
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: _ }) => {
+ AbstractConst::new(tcx, def, substs)
+ }
ty::ConstKind::Error(_) => Err(ErrorReported),
_ => Ok(None),
}
if let Some(next) = self.build_terminator(block.terminator())? {
block = &self.body.basic_blocks()[next];
} else {
- assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap());
+ break;
+ }
+ }
+
+ assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap());
+ for n in self.nodes.iter() {
+ if let Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(ct), ty: _ }) = n.node {
// `AbstractConst`s should not contain any promoteds as they require references which
// are not allowed.
- assert!(!self.nodes.iter().any(|n| matches!(
- n.node,
- Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(_, _, Some(_)), ty: _ })
- )));
-
- self.nodes[self.locals[mir::RETURN_PLACE]].used = true;
- if let Some(&unused) = self.nodes.iter().find(|n| !n.used) {
- self.error(Some(unused.span), "dead code")?;
- }
-
- return Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node)));
+ assert_eq!(ct.promoted, None);
}
}
+
+ self.nodes[self.locals[mir::RETURN_PLACE]].used = true;
+ if let Some(&unused) = self.nodes.iter().find(|n| !n.used) {
+ self.error(Some(unused.span), "dead code")?;
+ }
+
+ Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node)))
}
}
// we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
// means that we only allow inference variables if they are equal.
(ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => a_val == b_val,
- (
- ty::ConstKind::Unevaluated(a_def, a_substs, None),
- ty::ConstKind::Unevaluated(b_def, b_substs, None),
- ) => a_def == b_def && a_substs == b_substs,
+ // We expand generic anonymous constants at the start of this function, so this
+ // branch should only be taking when dealing with associated constants, at
+ // which point directly comparing them seems like the desired behavior.
+ //
+ // FIXME(const_evaluatable_checked): This isn't actually the case.
+ // We also take this branch for concrete anonymous constants and
+ // expand generic anonymous constants with concrete substs.
+ (ty::ConstKind::Unevaluated(a_uv), ty::ConstKind::Unevaluated(b_uv)) => {
+ a_uv == b_uv
+ }
// FIXME(const_evaluatable_checked): We may want to either actually try
// to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like
// this, for now we just return false here.
pub mod suggestions;
use super::{
- ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode,
- MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
- OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
- PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
+ EvaluationResult, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
+ Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedDirective,
+ OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, PredicateObligation,
+ SelectionContext, SelectionError, TraitNotObjectSafe,
};
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
-use rustc_middle::mir::interpret::ErrorHandled;
+use rustc_middle::mir::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::{
let violations = self.tcx.object_safety_violations(did);
report_object_safety_error(self.tcx, span, did, violations)
}
- ConstEvalFailure(ErrorHandled::TooGeneric) => {
- bug!("too generic should have been handled in `is_const_evaluatable`");
+
+ SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsInfer) => {
+ bug!(
+ "MentionsInfer should have been handled in `traits/fulfill.rs` or `traits/select/mod.rs`"
+ )
+ }
+ SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsParam) => {
+ if !self.tcx.features().const_evaluatable_checked {
+ let mut err = self.tcx.sess.struct_span_err(
+ span,
+ "constant expression depends on a generic parameter",
+ );
+ // FIXME(const_generics): we should suggest to the user how they can resolve this
+ // issue. However, this is currently not actually possible
+ // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083).
+ //
+ // Note that with `feature(const_evaluatable_checked)` this case should not
+ // be reachable.
+ err.note("this may fail depending on what value the parameter takes");
+ err.emit();
+ return;
+ }
+
+ match obligation.predicate.kind().skip_binder() {
+ ty::PredicateKind::ConstEvaluatable(def, _) => {
+ let mut err =
+ self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
+ let const_span = self.tcx.def_span(def.did);
+ match self.tcx.sess.source_map().span_to_snippet(const_span) {
+ Ok(snippet) => err.help(&format!(
+ "try adding a `where` bound using this expression: `where [(); {}]:`",
+ snippet
+ )),
+ _ => err.help("consider adding a `where` bound using this expression"),
+ };
+ err
+ }
+ _ => {
+ span_bug!(
+ span,
+ "unexpected non-ConstEvaluatable predicate, this should not be reachable"
+ )
+ }
+ }
}
+
// Already reported in the query.
- ConstEvalFailure(ErrorHandled::Reported(ErrorReported)) => {
+ SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(ErrorReported)) => {
// FIXME(eddyb) remove this once `ErrorReported` becomes a proof token.
self.tcx.sess.delay_span_bug(span, "`ErrorReported` without an error");
return;
}
- // Already reported in the query, but only as a lint.
- // This shouldn't actually happen for constants used in types, modulo
- // bugs. The `delay_span_bug` here ensures it won't be ignored.
- ConstEvalFailure(ErrorHandled::Linted) => {
- self.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
- return;
- }
-
Overflow => {
bug!("overflow should be handled before the `report_selection_error` path");
}
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
use rustc_errors::ErrorReported;
-use rustc_infer::traits::{TraitEngine, TraitEngineExt as _, TraitObligation};
+use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation};
+use rustc_middle::mir::abstract_const::NotConstEvaluatable;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::subst::SubstsRef;
use super::CodeAmbiguity;
use super::CodeProjectionError;
use super::CodeSelectionError;
-use super::{ConstEvalFailure, Unimplemented};
+use super::Unimplemented;
use super::{FulfillmentError, FulfillmentErrorCode};
use super::{ObligationCause, PredicateObligation};
obligation.cause.span,
) {
Ok(()) => ProcessResult::Changed(vec![]),
- Err(ErrorHandled::TooGeneric) => {
+ Err(NotConstEvaluatable::MentionsInfer) => {
pending_obligation.stalled_on.clear();
pending_obligation.stalled_on.extend(
substs.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg),
);
ProcessResult::Unchanged
}
- Err(e) => ProcessResult::Error(CodeSelectionError(ConstEvalFailure(e))),
+ Err(
+ e @ NotConstEvaluatable::MentionsParam
+ | e @ NotConstEvaluatable::Error(_),
+ ) => ProcessResult::Error(CodeSelectionError(
+ SelectionError::NotConstEvaluatable(e),
+ )),
}
}
// if the constants depend on generic parameters.
//
// Let's just see where this breaks :shrug:
- if let (
- ty::ConstKind::Unevaluated(a_def, a_substs, None),
- ty::ConstKind::Unevaluated(b_def, b_substs, None),
- ) = (c1.val, c2.val)
+ if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
+ (c1.val, c2.val)
{
if self
.selcx
.tcx()
- .try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs)))
+ .try_unify_abstract_consts(((a.def, a.substs), (b.def, b.substs)))
{
return ProcessResult::Changed(vec![]);
}
let stalled_on = &mut pending_obligation.stalled_on;
let mut evaluate = |c: &'tcx Const<'tcx>| {
- if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
+ if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
match self.selcx.infcx().const_eval_resolve(
obligation.param_env,
- def,
- substs,
- promoted,
+ unevaluated,
Some(obligation.cause.span),
) {
Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty)),
Err(ErrorHandled::TooGeneric) => {
stalled_on.extend(
- substs
+ unevaluated
+ .substs
.iter()
.filter_map(TyOrConstInferVar::maybe_from_generic_arg),
);
}
}
(Err(ErrorHandled::Reported(ErrorReported)), _)
- | (_, Err(ErrorHandled::Reported(ErrorReported))) => {
- ProcessResult::Error(CodeSelectionError(ConstEvalFailure(
- ErrorHandled::Reported(ErrorReported),
- )))
- }
+ | (_, Err(ErrorHandled::Reported(ErrorReported))) => ProcessResult::Error(
+ CodeSelectionError(SelectionError::NotConstEvaluatable(
+ NotConstEvaluatable::Error(ErrorReported),
+ )),
+ ),
(Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => {
span_bug!(
obligation.cause.span(self.selcx.tcx()),
use rustc_hir::Constness;
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
+use rustc_middle::mir::abstract_const::NotConstEvaluatable;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::fast_reject;
use rustc_middle::ty::print::with_no_trimmed_paths;
obligation.cause.span,
) {
Ok(()) => Ok(EvaluatedToOk),
- Err(ErrorHandled::TooGeneric) => Ok(EvaluatedToAmbig),
+ Err(NotConstEvaluatable::MentionsInfer) => Ok(EvaluatedToAmbig),
+ Err(NotConstEvaluatable::MentionsParam) => Ok(EvaluatedToErr),
Err(_) => Ok(EvaluatedToErr),
}
}
debug!(?c1, ?c2, "evaluate_predicate_recursively: equating consts");
let evaluate = |c: &'tcx ty::Const<'tcx>| {
- if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
+ if let ty::ConstKind::Unevaluated(unevaluated) = c.val {
self.infcx
.const_eval_resolve(
obligation.param_env,
- def,
- substs,
- promoted,
+ unevaluated,
Some(obligation.cause.span),
)
.map(|val| ty::Const::from_value(self.tcx(), val, c.ty))
GenericArgKind::Const(constant) => {
match constant.val {
- ty::ConstKind::Unevaluated(def, substs, promoted) => {
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
assert!(promoted.is_none());
let obligations = self.nominal_obligations(def.did, substs);
fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
let def_id = self.tcx.hir().local_def_id(c.hir_id);
let ct = ty::Const::from_anon_const(self.tcx, def_id);
- if let ty::ConstKind::Unevaluated(def, substs, None) = ct.val {
+ if let ty::ConstKind::Unevaluated(uv) = ct.val {
+ assert_eq!(uv.promoted, None);
let span = self.tcx.hir().span(c.hir_id);
self.preds.insert((
- ty::PredicateKind::ConstEvaluatable(def, substs).to_predicate(self.tcx),
+ ty::PredicateKind::ConstEvaluatable(uv.def, uv.substs).to_predicate(self.tcx),
span,
));
}
/// };
/// ```
///
-/// For more information on the `move` keyword, see the [closure]'s section
-/// of the Rust book or the [threads] section
+/// For more information on the `move` keyword, see the [closures][closure] section
+/// of the Rust book or the [threads] section.
///
/// [closure]: ../book/ch13-01-closures.html
/// [threads]: ../book/ch16-01-threads.html#using-move-closures-with-threads
crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
match n.val {
- ty::ConstKind::Unevaluated(def, _, promoted) => {
+ ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs: _, promoted }) => {
let mut s = if let Some(def) = def.as_local() {
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did);
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(hir_id))
- // + ty: &i32
- // + val: Value(Scalar(alloc0))
+ // + ty: &[&i32; 1]
-+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, [], Some(promoted[0]))
++ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
- // + literal: Const { ty: &i32, val: Value(Scalar(alloc0)) }
- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
+ // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:35
-+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, [], Some(promoted[0])) }
++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
_1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:9:34: 9:35
- // + ty: *const i32
- // + val: Value(Scalar(alloc2))
+ // + ty: &[&i32; 1]
-+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0]))
++ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) }
- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
+ // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:46
-+ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0])) }
++ // + literal: Const { ty: &[&i32; 1], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
_1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
- StorageDead(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:13:45: 13:46
_9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
// ty::Const
// + ty: &[i32; 3]
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
- // + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
_2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
_1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
_9 = const main::promoted[0]; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
// ty::Const
// + ty: &[i32; 3]
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
- // + literal: Const { ty: &[i32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &[i32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ bad_op_unsafe_oob_for_slices[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
_2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
_1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35
_3 = const FOO; // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, [], None)
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, substs: [], promoted: None })
// mir::Constant
// + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, [], None) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ const_prop_fails_gracefully[317d]::main::FOO), const_param_did: None }, substs: [], promoted: None }) }
_2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
_1 = move _2 as usize (Misc); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:39
StorageDead(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:38: 7:39
_4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/ref_deref.rs:5:6: 5:10
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_2 = _4; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
- _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
+ _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
+ // ty::Const
+ // + ty: &i32
-+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0]))
++ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
+ // mir::Constant
+ // + span: $DIR/ref_deref.rs:5:6: 5:10
-+ // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
++ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
+ _2 = &(*_4); // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
_1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
- StorageDead(_3); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11
_4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
// ty::Const
// + ty: &(i32, i32)
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/ref_deref_project.rs:5:6: 5:17
- // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
_1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
+ _4 = const main::promoted[0]; // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
+ // ty::Const
+ // + ty: &(i32, i32)
-+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0]))
++ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
+ // mir::Constant
+ // + span: $DIR/ref_deref_project.rs:5:6: 5:17
-+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
++ // + literal: Const { ty: &(i32, i32), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
+ _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
_1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
- StorageDead(_3); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
_9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
// ty::Const
// + ty: &[u32; 3]
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/slice_len.rs:5:6: 5:19
- // + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
_3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
_2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
_9 = const main::promoted[0]; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
// ty::Const
// + ty: &[u32; 3]
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/slice_len.rs:5:6: 5:19
- // + literal: Const { ty: &[u32; 3], val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &[u32; 3], val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ slice_len[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_4 = _9; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
_3 = _4; // scope 0 at $DIR/slice_len.rs:5:6: 5:19
_2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:5:6: 5:19
_10 = const bar::promoted[1]; // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[1]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[1]) })
// mir::Constant
// + span: $DIR/inline-retag.rs:12:7: 12:9
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[1])) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[1]) }) }
Retag(_10); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
_4 = &(*_10); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
Retag(_4); // scope 1 at $DIR/inline-retag.rs:12:7: 12:9
_9 = const bar::promoted[0]; // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/inline-retag.rs:12:11: 12:14
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:4 ~ inline_retag[317d]::bar), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
Retag(_9); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
_7 = &(*_9); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
Retag(_7); // scope 1 at $DIR/inline-retag.rs:12:11: 12:14
_20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_8 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_6.0: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_6.1: &i32) = move _8; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_8 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_6.0: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_6.1: &i32) = move _8; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_28 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_9.0: &i32) = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
(_9.1: &i32) = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL
_19 = const discriminant::<T>::promoted[2]; // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[2]) })
// mir::Constant
// + span: $DIR/lower_intrinsics.rs:70:42: 70:44
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[2])) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[2]) }) }
_7 = &(*_19); // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
_6 = &(*_7); // scope 0 at $DIR/lower_intrinsics.rs:70:42: 70:44
- _5 = discriminant_value::<i32>(move _6) -> bb2; // scope 0 at $DIR/lower_intrinsics.rs:70:5: 70:45
_18 = const discriminant::<T>::promoted[1]; // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
// ty::Const
// + ty: &()
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[1]) })
// mir::Constant
// + span: $DIR/lower_intrinsics.rs:71:42: 71:45
- // + literal: Const { ty: &(), val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[1])) }
+ // + literal: Const { ty: &(), val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[1]) }) }
_11 = &(*_18); // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
_10 = &(*_11); // scope 0 at $DIR/lower_intrinsics.rs:71:42: 71:45
- _9 = discriminant_value::<()>(move _10) -> bb3; // scope 0 at $DIR/lower_intrinsics.rs:71:5: 71:46
_17 = const discriminant::<T>::promoted[0]; // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
// ty::Const
// + ty: &E
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/lower_intrinsics.rs:72:42: 72:47
- // + literal: Const { ty: &E, val: Unevaluated(WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, [T], Some(promoted[0])) }
+ // + literal: Const { ty: &E, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:27 ~ lower_intrinsics[8787]::discriminant), const_param_did: None }, substs: [T], promoted: Some(promoted[0]) }) }
_15 = &(*_17); // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
_14 = &(*_15); // scope 0 at $DIR/lower_intrinsics.rs:72:42: 72:47
- _13 = discriminant_value::<E>(move _14) -> bb4; // scope 0 at $DIR/lower_intrinsics.rs:72:5: 72:48
_11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
// ty::Const
// + ty: &std::option::Option<i32>
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/match_false_edges.rs:16:14: 16:15
- // + literal: Const { ty: &std::option::Option<i32>, val: Unevaluated(WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &std::option::Option<i32>, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:5 ~ match_false_edges[317d]::full_tested_match), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
_6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
_4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:16:20: 16:27
_27 = const main::promoted[0]; // scope 7 at $DIR/retag.rs:47:21: 47:23
// ty::Const
// + ty: &i32
- // + val: Unevaluated(WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, [], Some(promoted[0]))
+ // + val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) })
// mir::Constant
// + span: $DIR/retag.rs:47:21: 47:23
- // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
+ // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:13 ~ retag[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) }
Retag(_27); // scope 7 at $DIR/retag.rs:47:21: 47:23
_23 = &(*_27); // scope 7 at $DIR/retag.rs:47:21: 47:23
Retag(_23); // scope 7 at $DIR/retag.rs:47:21: 47:23
--- /dev/null
+// run-pass
+trait TheTrait : TheSuperTrait<<Self as TheTrait>::Item> {
+ type Item;
+}
+
+trait TheSuperTrait<T> {
+ fn get(&self) -> T;
+}
+
+impl TheTrait for i32 {
+ type Item = u32;
+}
+
+impl TheSuperTrait<u32> for i32 {
+ fn get(&self) -> u32 {
+ *self as u32
+ }
+}
+
+fn foo<T:TheTrait<Item=u32>>(t: &T) -> u32 {
+ t.get()
+}
+
+fn main() {
+ foo::<i32>(&22);
+}
--- /dev/null
+// check-pass
+#![allow(dead_code)]
+trait Make {
+ type Out;
+
+ fn make() -> Self::Out;
+}
+
+impl Make for () {
+ type Out = ();
+
+ fn make() -> Self::Out {}
+}
+
+// Also make sure we don't hit an ICE when the projection can't be known
+fn f<T: Make>() -> <T as Make>::Out { loop {} }
+
+// ...and that it works with a blanket impl
+trait Tr {
+ type Assoc;
+}
+
+impl<T: Make> Tr for T {
+ type Assoc = ();
+}
+
+fn g<T: Make>() -> <T as Tr>::Assoc { }
+
+fn main() {}
--- /dev/null
+// run-pass
+
+#![allow(non_camel_case_types)]
+#![allow(dead_code)]
+fn foo(c: Vec<isize> ) {
+ let a: isize = 5;
+ let mut b: Vec<isize> = Vec::new();
+
+
+ match t::none::<isize> {
+ t::some::<isize>(_) => {
+ for _i in &c {
+ println!("{}", a);
+ let a = 17;
+ b.push(a);
+ }
+ }
+ _ => { }
+ }
+}
+
+enum t<T> { none, some(T), }
+
+pub fn main() { let x = 10; let x = x + 20; assert_eq!(x, 30); foo(Vec::new()); }
+++ /dev/null
-// run-pass
-
-pub fn main() {
- assert_eq!(format!(concat!("foo", "bar", "{}"), "baz"), "foobarbaz".to_string());
- assert_eq!(format!(concat!()), "".to_string());
- // check trailing comma is allowed in concat
- assert_eq!(concat!("qux", "quux",).to_string(), "quxquux".to_string());
-
- assert_eq!(
- concat!(1, 2, 3, 4f32, 4.0, 'a', true),
- "12344.0atrue"
- );
-
- assert!(match "12344.0atrue" {
- concat!(1, 2, 3, 4f32, 4.0, 'a', true) => true,
- _ => false
- })
-}
|
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::<T>() - 1]: Sized`
- --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
+ |
+ ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10
|
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ---------------------------- required by this bound in `test1`
+ |
+ = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:13
|
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::<T>() - 1]: Sized`
- --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27
+ |
+ ::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27
|
LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ---------------------------- required by this bound in `test1`
+ |
+ = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:13
|
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::<T>() - 1]: Sized`
- --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
+ |
+ ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10
|
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ---------------------------- required by this bound in `test1`
+ |
+ = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:13
|
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::<T>() - 1]: Sized`
- --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27
+ |
+ ::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27
|
LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ---------------------------- required by this bound in `test1`
+ |
+ = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
error: aborting due to 4 previous errors
LL | [0; size_of::<Foo<T>>()]
| ^^^^^^^^^^^^^^^^^^^
|
-help: try adding a `where` bound using this expression: `where [u8; size_of::<Foo<T>>()]: Sized`
- --> $DIR/different-fn.rs:10:9
- |
-LL | [0; size_of::<Foo<T>>()]
- | ^^^^^^^^^^^^^^^^^^^
+ = help: try adding a `where` bound using this expression: `where [(); size_of::<Foo<T>>()]:`
error: aborting due to previous error
--- /dev/null
+// run-pass
+#![feature(const_generics)]
+#![feature(const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+// This test is a repro for #82279. It checks that we don't error
+// when calling is_const_evaluatable on `std::mem::size_of::<T>()`
+// when looking for candidates that may prove `T: Foo` in `foo`
+
+trait Foo {}
+
+#[allow(dead_code)]
+fn foo<T: Foo>() {}
+
+impl<T> Foo for T where [(); std::mem::size_of::<T>()]: {}
+
+fn main() {}
LL | b: [f32; complex_maths::<T>(N)],
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-help: try adding a `where` bound using this expression: `where [u8; complex_maths::<T>(N)]: Sized`
- --> $DIR/needs_where_clause.rs:11:12
- |
-LL | b: [f32; complex_maths::<T>(N)],
- | ^^^^^^^^^^^^^^^^^^^^^
+ = help: try adding a `where` bound using this expression: `where [(); complex_maths::<T>(N)]:`
error: aborting due to previous error
LL | b: [f32; complex_maths(N)],
| ^^^^^^^^^^^^^^^^^^^^^^^
|
-help: try adding a `where` bound using this expression: `where [u8; complex_maths(N)]: Sized`
- --> $DIR/no_where_clause.rs:10:12
- |
-LL | b: [f32; complex_maths(N)],
- | ^^^^^^^^^^^^^^^^
+ = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:`
error: aborting due to previous error
--- /dev/null
+// Regression test for https://github.com/rust-lang/rust/issues/52060
+// The compiler shouldn't ICE in this case
+static A: &'static [u32] = &[1];
+static B: [u32; 1] = [0; A.len()];
+//~^ ERROR [E0013]
+
+fn main() {}
--- /dev/null
+error[E0013]: constants cannot refer to statics
+ --> $DIR/issue-52060.rs:4:26
+ |
+LL | static B: [u32; 1] = [0; A.len()];
+ | ^
+ |
+ = help: consider extracting the value of the `static` to a `const`, and referring to that
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0013`.
--- /dev/null
+#![allow(dead_code)]
+
+struct Foo { a: u8 }
+fn bar() -> Foo {
+ Foo { a: 5 }
+}
+
+static foo: Foo = bar();
+//~^ ERROR calls in statics are limited to constant functions, tuple structs and tuple variants
+
+fn main() {}
--- /dev/null
+error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
+ --> $DIR/mir_check_nonconst.rs:8:19
+ |
+LL | static foo: Foo = bar();
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
+++ /dev/null
-// check-pass
-
-#![warn(unused_must_use)]
-
-#[derive(PartialEq, Eq)]
-struct MyStruct {
- n: usize,
-}
-
-impl MyStruct {
- #[must_use]
- fn need_to_use_this_method_value(&self) -> usize {
- self.n
- }
-
- #[must_use]
- fn need_to_use_this_associated_function_value() -> isize {
- -1
- }
-}
-
-trait EvenNature {
- #[must_use = "no side effects"]
- fn is_even(&self) -> bool;
-}
-
-impl EvenNature for MyStruct {
- fn is_even(&self) -> bool {
- self.n % 2 == 0
- }
-}
-
-trait Replaceable {
- fn replace(&mut self, substitute: usize) -> usize;
-}
-
-impl Replaceable for MyStruct {
- // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation
- // method won't work; the attribute should be on the method signature in
- // the trait's definition.
- #[must_use]
- fn replace(&mut self, substitute: usize) -> usize {
- let previously = self.n;
- self.n = substitute;
- previously
- }
-}
-
-#[must_use = "it's important"]
-fn need_to_use_this_value() -> bool {
- false
-}
-
-fn main() {
- need_to_use_this_value(); //~ WARN unused return value
-
- let mut m = MyStruct { n: 2 };
- let n = MyStruct { n: 3 };
-
- m.need_to_use_this_method_value(); //~ WARN unused return value
- m.is_even(); // trait method!
- //~^ WARN unused return value
-
- MyStruct::need_to_use_this_associated_function_value();
- //~^ WARN unused return value
-
- m.replace(3); // won't warn (annotation needs to be in trait definition)
-
- // comparison methods are `must_use`
- 2.eq(&3); //~ WARN unused return value
- m.eq(&n); //~ WARN unused return value
-
- // lint includes comparison operators
- 2 == 3; //~ WARN unused comparison
- m == n; //~ WARN unused comparison
-}
+++ /dev/null
-warning: unused return value of `need_to_use_this_value` that must be used
- --> $DIR/fn_must_use.rs:55:5
- |
-LL | need_to_use_this_value();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: the lint level is defined here
- --> $DIR/fn_must_use.rs:3:9
- |
-LL | #![warn(unused_must_use)]
- | ^^^^^^^^^^^^^^^
- = note: it's important
-
-warning: unused return value of `MyStruct::need_to_use_this_method_value` that must be used
- --> $DIR/fn_must_use.rs:60:5
- |
-LL | m.need_to_use_this_method_value();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused return value of `EvenNature::is_even` that must be used
- --> $DIR/fn_must_use.rs:61:5
- |
-LL | m.is_even(); // trait method!
- | ^^^^^^^^^^^^
- |
- = note: no side effects
-
-warning: unused return value of `MyStruct::need_to_use_this_associated_function_value` that must be used
- --> $DIR/fn_must_use.rs:64:5
- |
-LL | MyStruct::need_to_use_this_associated_function_value();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused return value of `std::cmp::PartialEq::eq` that must be used
- --> $DIR/fn_must_use.rs:70:5
- |
-LL | 2.eq(&3);
- | ^^^^^^^^^
-
-warning: unused return value of `std::cmp::PartialEq::eq` that must be used
- --> $DIR/fn_must_use.rs:71:5
- |
-LL | m.eq(&n);
- | ^^^^^^^^^
-
-warning: unused comparison that must be used
- --> $DIR/fn_must_use.rs:74:5
- |
-LL | 2 == 3;
- | ^^^^^^
-
-warning: unused comparison that must be used
- --> $DIR/fn_must_use.rs:75:5
- |
-LL | m == n;
- | ^^^^^^
-
-warning: 8 warnings emitted
-
--- /dev/null
+#![feature(generators)]
+
+fn main() {
+ let _ = || {
+ *(1 as *mut u32) = 42;
+ //~^ ERROR dereference of raw pointer is unsafe
+ yield;
+ };
+}
--- /dev/null
+error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
+ --> $DIR/issue-45729-unsafe-in-generator.rs:5:9
+ |
+LL | *(1 as *mut u32) = 42;
+ | ^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer
+ |
+ = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
+++ /dev/null
-// check-pass
-
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-const _: impl Fn() = ||();
-
-fn main() {}
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/impl-trait-in-bindings-issue-73003.rs:3:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
+++ /dev/null
-// run-pass
-
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-use std::fmt::Debug;
-
-const FOO: impl Debug + Clone + PartialEq<i32> = 42;
-
-static BAR: impl Debug + Clone + PartialEq<i32> = 42;
-
-fn a<T: Clone>(x: T) {
- let y: impl Clone = x;
- let _ = y.clone();
-}
-
-fn b<T: Clone>(x: T) {
- let f = move || {
- let y: impl Clone = x;
- let _ = y.clone();
- };
- f();
-}
-
-trait Foo<T: Clone> {
- fn a(x: T) {
- let y: impl Clone = x;
- let _ = y.clone();
- }
-}
-
-impl<T: Clone> Foo<T> for i32 {
- fn a(x: T) {
- let y: impl Clone = x;
- let _ = y.clone();
- }
-}
-
-fn main() {
- let foo: impl Debug + Clone + PartialEq<i32> = 42;
-
- assert_eq!(FOO.clone(), 42);
- assert_eq!(BAR.clone(), 42);
- assert_eq!(foo.clone(), 42);
-
- a(42);
- b(42);
- i32::a(42);
-}
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/impl-trait-in-bindings.rs:3:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
--- /dev/null
+// check-pass
+
+#![feature(impl_trait_in_bindings)]
+//~^ WARN the feature `impl_trait_in_bindings` is incomplete
+
+const _: impl Fn() = ||();
+
+fn main() {}
--- /dev/null
+warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/impl-trait-in-bindings-issue-73003.rs:3:12
+ |
+LL | #![feature(impl_trait_in_bindings)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+
+warning: 1 warning emitted
+
--- /dev/null
+// run-pass
+
+#![feature(impl_trait_in_bindings)]
+//~^ WARN the feature `impl_trait_in_bindings` is incomplete
+
+use std::fmt::Debug;
+
+const FOO: impl Debug + Clone + PartialEq<i32> = 42;
+
+static BAR: impl Debug + Clone + PartialEq<i32> = 42;
+
+fn a<T: Clone>(x: T) {
+ let y: impl Clone = x;
+ let _ = y.clone();
+}
+
+fn b<T: Clone>(x: T) {
+ let f = move || {
+ let y: impl Clone = x;
+ let _ = y.clone();
+ };
+ f();
+}
+
+trait Foo<T: Clone> {
+ fn a(x: T) {
+ let y: impl Clone = x;
+ let _ = y.clone();
+ }
+}
+
+impl<T: Clone> Foo<T> for i32 {
+ fn a(x: T) {
+ let y: impl Clone = x;
+ let _ = y.clone();
+ }
+}
+
+fn main() {
+ let foo: impl Debug + Clone + PartialEq<i32> = 42;
+
+ assert_eq!(FOO.clone(), 42);
+ assert_eq!(BAR.clone(), 42);
+ assert_eq!(foo.clone(), 42);
+
+ a(42);
+ b(42);
+ i32::a(42);
+}
--- /dev/null
+warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/impl-trait-in-bindings.rs:3:12
+ |
+LL | #![feature(impl_trait_in_bindings)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+
+warning: 1 warning emitted
+
+++ /dev/null
-// run-pass
-#![allow(unused_variables)]
-
-struct A { foo: isize }
-struct B { a: isize, b: isize, c: isize }
-
-fn mka() -> A { panic!() }
-fn mkb() -> B { panic!() }
-
-fn test() {
- let A { foo, } = mka();
- let A {
- foo,
- } = mka();
-
- let B { a, b, c, } = mkb();
-
- match mka() {
- A { foo: _foo, } => {}
- }
-
- match Some(mka()) {
- Some(A { foo: _foo, }) => {}
- None => {}
- }
-}
-
-pub fn main() {
- if false { test() }
-}
+++ /dev/null
-// run-pass
-#![allow(dead_code)]
-#![allow(non_camel_case_types)]
-
-
-enum pattern { tabby, tortoiseshell, calico }
-enum breed { beagle, rottweiler, pug }
-type name = String;
-enum ear_kind { lop, upright }
-enum animal { cat(pattern), dog(breed), rabbit(name, ear_kind), tiger }
-
-fn noise(a: animal) -> Option<String> {
- match a {
- animal::cat(..) => { Some("meow".to_string()) }
- animal::dog(..) => { Some("woof".to_string()) }
- animal::rabbit(..) => { None }
- animal::tiger => { Some("roar".to_string()) }
- }
-}
-
-pub fn main() {
- assert_eq!(noise(animal::cat(pattern::tabby)), Some("meow".to_string()));
- assert_eq!(noise(animal::dog(breed::pug)), Some("woof".to_string()));
- assert_eq!(noise(animal::rabbit("Hilbert".to_string(), ear_kind::upright)), None);
- assert_eq!(noise(animal::tiger), Some("roar".to_string()));
-}
+++ /dev/null
-// run-pass
-trait TheTrait : TheSuperTrait<<Self as TheTrait>::Item> {
- type Item;
-}
-
-trait TheSuperTrait<T> {
- fn get(&self) -> T;
-}
-
-impl TheTrait for i32 {
- type Item = u32;
-}
-
-impl TheSuperTrait<u32> for i32 {
- fn get(&self) -> u32 {
- *self as u32
- }
-}
-
-fn foo<T:TheTrait<Item=u32>>(t: &T) -> u32 {
- t.get()
-}
-
-fn main() {
- foo::<i32>(&22);
-}
+++ /dev/null
-// check-pass
-#![allow(dead_code)]
-trait Make {
- type Out;
-
- fn make() -> Self::Out;
-}
-
-impl Make for () {
- type Out = ();
-
- fn make() -> Self::Out {}
-}
-
-// Also make sure we don't hit an ICE when the projection can't be known
-fn f<T: Make>() -> <T as Make>::Out { loop {} }
-
-// ...and that it works with a blanket impl
-trait Tr {
- type Assoc;
-}
-
-impl<T: Make> Tr for T {
- type Assoc = ();
-}
-
-fn g<T: Make>() -> <T as Tr>::Assoc { }
-
-fn main() {}
+++ /dev/null
-#![feature(generators)]
-
-fn main() {
- let _ = || {
- *(1 as *mut u32) = 42;
- //~^ ERROR dereference of raw pointer is unsafe
- yield;
- };
-}
+++ /dev/null
-error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
- --> $DIR/issue-45729-unsafe-in-generator.rs:5:9
- |
-LL | *(1 as *mut u32) = 42;
- | ^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer
- |
- = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
+++ /dev/null
-// run-pass
-// ignore-test Not a test. Used by issue-48508.rs
-
-pub fn other() -> f64 {
- let µ = 1.0;
- µ
-}
+++ /dev/null
-// run-pass
-// Regression test for issue #48508:
-//
-// Confusion between global and local file offsets caused incorrect handling of multibyte character
-// spans when compiling multiple files. One visible effect was an ICE generating debug information
-// when a multibyte character is at the end of a scope. The problematic code is actually in
-// issue-48508-aux.rs
-
-// compile-flags:-g
-// ignore-pretty issue #37195
-// ignore-asmjs wasm2js does not support source maps yet
-
-#![feature(non_ascii_idents)]
-#![allow(uncommon_codepoints)]
-
-#[path = "issue-48508-aux.rs"]
-mod other_file;
-
-fn main() {
- other_file::other();
-}
+++ /dev/null
-// Regression test for https://github.com/rust-lang/rust/issues/52060
-// The compiler shouldn't ICE in this case
-static A: &'static [u32] = &[1];
-static B: [u32; 1] = [0; A.len()];
-//~^ ERROR [E0013]
-
-fn main() {}
+++ /dev/null
-error[E0013]: constants cannot refer to statics
- --> $DIR/issue-52060.rs:4:26
- |
-LL | static B: [u32; 1] = [0; A.len()];
- | ^
- |
- = help: consider extracting the value of the `static` to a `const`, and referring to that
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0013`.
+++ /dev/null
-use std::mem::MaybeUninit;
-use std::ops::Deref;
-
-pub unsafe trait Array {
- /// The array’s element type
- type Item;
- #[doc(hidden)]
- /// The smallest index type that indexes the array.
- type Index: Index;
- #[doc(hidden)]
- fn as_ptr(&self) -> *const Self::Item;
- #[doc(hidden)]
- fn as_mut_ptr(&mut self) -> *mut Self::Item;
- #[doc(hidden)]
- fn capacity() -> usize;
-}
-
-pub trait Index : PartialEq + Copy {
- fn to_usize(self) -> usize;
- fn from(usize) -> Self;
-}
-
-impl Index for usize {
- fn to_usize(self) -> usize { self }
- fn from(val: usize) -> Self {
- val
- }
-}
-
-unsafe impl<T> Array for [T; 1] {
- type Item = T;
- type Index = usize;
- fn as_ptr(&self) -> *const T { self as *const _ as *const _ }
- fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _}
- fn capacity() -> usize { 1 }
-}
-
-impl<A: Array> Deref for ArrayVec<A> {
- type Target = [A::Item];
- #[inline]
- fn deref(&self) -> &[A::Item] {
- panic!()
- }
-}
-
-pub struct ArrayVec<A: Array> {
- xs: MaybeUninit<A>,
- len: usize,
-}
-
-impl<A: Array> ArrayVec<A> {
- pub fn new() -> ArrayVec<A> {
- panic!()
- }
-}
-
-fn main() {
- let mut buffer = ArrayVec::new();
- let x = buffer.last().unwrap().0.clone();
- //~^ ERROR type annotations needed
- //~| ERROR no field `0` on type `&_`
- buffer.reverse();
-}
+++ /dev/null
-error[E0282]: type annotations needed
- --> $DIR/issue-65611.rs:59:20
- |
-LL | let x = buffer.last().unwrap().0.clone();
- | -------^^^^--
- | | |
- | | cannot infer type for type parameter `T`
- | this method call resolves to `Option<&T>`
- |
- = note: type must be known at this point
-
-error[E0609]: no field `0` on type `&_`
- --> $DIR/issue-65611.rs:59:36
- |
-LL | let x = buffer.last().unwrap().0.clone();
- | ^
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0282, E0609.
-For more information about an error, try `rustc --explain E0282`.
+++ /dev/null
-pub struct Foo {
- pub bar: Vec<i32>ö
- //~^ ERROR expected `,`, or `}`, found `ö`
-} //~ ERROR expected `:`, found `}`
-
-fn main() {}
+++ /dev/null
-error: expected `,`, or `}`, found `ö`
- --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:2:22
- |
-LL | pub bar: Vec<i32>ö
- | ^ help: try adding a comma: `,`
-
-error: expected `:`, found `}`
- --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:4:1
- |
-LL | pub bar: Vec<i32>ö
- | - expected `:`
-LL |
-LL | }
- | ^ unexpected token
-
-error: aborting due to 2 previous errors
-
+++ /dev/null
-use std::ops::DispatchFromDyn; //~ ERROR use of unstable library feature 'dispatch_from_dyn'
-struct Smaht<T, MISC>(PhantomData); //~ ERROR cannot find type `PhantomData` in this scope
-impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {} //~ ERROR cannot find type `U` in this scope
-//~^ ERROR cannot find type `MISC` in this scope
-//~| ERROR use of unstable library feature 'dispatch_from_dyn'
-//~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures
-//~| ERROR type parameter `T` must be covered by another type when it appears before the first
-trait Foo: X<u32> {}
-trait X<T> {
- fn foo(self: Smaht<Self, T>);
-}
-trait Marker {}
-impl Marker for dyn Foo {}
-fn main() {}
+++ /dev/null
-error[E0412]: cannot find type `PhantomData` in this scope
- --> $DIR/issue-78372.rs:2:23
- |
-LL | struct Smaht<T, MISC>(PhantomData);
- | ^^^^^^^^^^^ not found in this scope
- |
-help: consider importing this struct
- |
-LL | use std::marker::PhantomData;
- |
-
-error[E0412]: cannot find type `U` in this scope
- --> $DIR/issue-78372.rs:3:31
- |
-LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
- | - ^ help: a type parameter with a similar name exists: `T`
- | |
- | similarly named type parameter `T` defined here
-
-error[E0412]: cannot find type `MISC` in this scope
- --> $DIR/issue-78372.rs:3:34
- |
-LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
- | - ^^^^ not found in this scope
- | |
- | help: you might be missing a type parameter: `, MISC`
-
-error[E0658]: use of unstable library feature 'dispatch_from_dyn'
- --> $DIR/issue-78372.rs:1:5
- |
-LL | use std::ops::DispatchFromDyn;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
-
-error[E0658]: use of unstable library feature 'dispatch_from_dyn'
- --> $DIR/issue-78372.rs:3:9
- |
-LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
-
-error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
- --> $DIR/issue-78372.rs:3:1
- |
-LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
- --> $DIR/issue-78372.rs:3:6
- |
-LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
- | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
- |
- = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
- = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
-
-error: aborting due to 7 previous errors
-
-Some errors have detailed explanations: E0210, E0378, E0412, E0658.
-For more information about an error, try `rustc --explain E0210`.
--- /dev/null
+// check-pass
+
+#![warn(unused_must_use)]
+
+#[derive(PartialEq, Eq)]
+struct MyStruct {
+ n: usize,
+}
+
+impl MyStruct {
+ #[must_use]
+ fn need_to_use_this_method_value(&self) -> usize {
+ self.n
+ }
+
+ #[must_use]
+ fn need_to_use_this_associated_function_value() -> isize {
+ -1
+ }
+}
+
+trait EvenNature {
+ #[must_use = "no side effects"]
+ fn is_even(&self) -> bool;
+}
+
+impl EvenNature for MyStruct {
+ fn is_even(&self) -> bool {
+ self.n % 2 == 0
+ }
+}
+
+trait Replaceable {
+ fn replace(&mut self, substitute: usize) -> usize;
+}
+
+impl Replaceable for MyStruct {
+ // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation
+ // method won't work; the attribute should be on the method signature in
+ // the trait's definition.
+ #[must_use]
+ fn replace(&mut self, substitute: usize) -> usize {
+ let previously = self.n;
+ self.n = substitute;
+ previously
+ }
+}
+
+#[must_use = "it's important"]
+fn need_to_use_this_value() -> bool {
+ false
+}
+
+fn main() {
+ need_to_use_this_value(); //~ WARN unused return value
+
+ let mut m = MyStruct { n: 2 };
+ let n = MyStruct { n: 3 };
+
+ m.need_to_use_this_method_value(); //~ WARN unused return value
+ m.is_even(); // trait method!
+ //~^ WARN unused return value
+
+ MyStruct::need_to_use_this_associated_function_value();
+ //~^ WARN unused return value
+
+ m.replace(3); // won't warn (annotation needs to be in trait definition)
+
+ // comparison methods are `must_use`
+ 2.eq(&3); //~ WARN unused return value
+ m.eq(&n); //~ WARN unused return value
+
+ // lint includes comparison operators
+ 2 == 3; //~ WARN unused comparison
+ m == n; //~ WARN unused comparison
+}
--- /dev/null
+warning: unused return value of `need_to_use_this_value` that must be used
+ --> $DIR/fn_must_use.rs:55:5
+ |
+LL | need_to_use_this_value();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/fn_must_use.rs:3:9
+ |
+LL | #![warn(unused_must_use)]
+ | ^^^^^^^^^^^^^^^
+ = note: it's important
+
+warning: unused return value of `MyStruct::need_to_use_this_method_value` that must be used
+ --> $DIR/fn_must_use.rs:60:5
+ |
+LL | m.need_to_use_this_method_value();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused return value of `EvenNature::is_even` that must be used
+ --> $DIR/fn_must_use.rs:61:5
+ |
+LL | m.is_even(); // trait method!
+ | ^^^^^^^^^^^^
+ |
+ = note: no side effects
+
+warning: unused return value of `MyStruct::need_to_use_this_associated_function_value` that must be used
+ --> $DIR/fn_must_use.rs:64:5
+ |
+LL | MyStruct::need_to_use_this_associated_function_value();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused return value of `std::cmp::PartialEq::eq` that must be used
+ --> $DIR/fn_must_use.rs:70:5
+ |
+LL | 2.eq(&3);
+ | ^^^^^^^^^
+
+warning: unused return value of `std::cmp::PartialEq::eq` that must be used
+ --> $DIR/fn_must_use.rs:71:5
+ |
+LL | m.eq(&n);
+ | ^^^^^^^^^
+
+warning: unused comparison that must be used
+ --> $DIR/fn_must_use.rs:74:5
+ |
+LL | 2 == 3;
+ | ^^^^^^
+
+warning: unused comparison that must be used
+ --> $DIR/fn_must_use.rs:75:5
+ |
+LL | m == n;
+ | ^^^^^^
+
+warning: 8 warnings emitted
+
--- /dev/null
+// run-pass
+
+pub fn main() {
+ assert_eq!(format!(concat!("foo", "bar", "{}"), "baz"), "foobarbaz".to_string());
+ assert_eq!(format!(concat!()), "".to_string());
+ // check trailing comma is allowed in concat
+ assert_eq!(concat!("qux", "quux",).to_string(), "quxquux".to_string());
+
+ assert_eq!(
+ concat!(1, 2, 3, 4f32, 4.0, 'a', true),
+ "12344.0atrue"
+ );
+
+ assert!(match "12344.0atrue" {
+ concat!(1, 2, 3, 4f32, 4.0, 'a', true) => true,
+ _ => false
+ })
+}
+++ /dev/null
-#![allow(dead_code)]
-
-struct Foo { a: u8 }
-fn bar() -> Foo {
- Foo { a: 5 }
-}
-
-static foo: Foo = bar();
-//~^ ERROR calls in statics are limited to constant functions, tuple structs and tuple variants
-
-fn main() {}
+++ /dev/null
-error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
- --> $DIR/mir_check_nonconst.rs:8:19
- |
-LL | static foo: Foo = bar();
- | ^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0015`.
+++ /dev/null
-#![no_implicit_prelude]
-
-// Test that things from the prelude aren't in scope. Use many of them
-// so that renaming some things won't magically make this test fail
-// for the wrong reason (e.g., if `Add` changes to `Addition`, and
-// `no_implicit_prelude` stops working, then the `impl Add` will still
-// fail with the same error message).
-
-struct Test;
-impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope
-impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone`
-impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope
-impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope
-impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope
-
-fn main() {
- drop(2) //~ ERROR cannot find function `drop` in this scope
-}
+++ /dev/null
-error[E0405]: cannot find trait `Add` in this scope
- --> $DIR/no-implicit-prelude.rs:10:6
- |
-LL | impl Add for Test {}
- | ^^^ not found in this scope
- |
-help: consider importing this trait
- |
-LL | use std::ops::Add;
- |
-
-error[E0404]: expected trait, found derive macro `Clone`
- --> $DIR/no-implicit-prelude.rs:11:6
- |
-LL | impl Clone for Test {}
- | ^^^^^ not a trait
- |
-help: consider importing this trait instead
- |
-LL | use std::clone::Clone;
- |
-
-error[E0405]: cannot find trait `Iterator` in this scope
- --> $DIR/no-implicit-prelude.rs:12:6
- |
-LL | impl Iterator for Test {}
- | ^^^^^^^^ not found in this scope
- |
-help: consider importing this trait
- |
-LL | use std::iter::Iterator;
- |
-
-error[E0405]: cannot find trait `ToString` in this scope
- --> $DIR/no-implicit-prelude.rs:13:6
- |
-LL | impl ToString for Test {}
- | ^^^^^^^^ not found in this scope
- |
-help: consider importing this trait
- |
-LL | use std::string::ToString;
- |
-
-error[E0405]: cannot find trait `Writer` in this scope
- --> $DIR/no-implicit-prelude.rs:14:6
- |
-LL | impl Writer for Test {}
- | ^^^^^^ not found in this scope
-
-error[E0425]: cannot find function `drop` in this scope
- --> $DIR/no-implicit-prelude.rs:17:5
- |
-LL | drop(2)
- | ^^^^ not found in this scope
- |
-help: consider importing this function
- |
-LL | use std::mem::drop;
- |
-
-error: aborting due to 6 previous errors
-
-Some errors have detailed explanations: E0404, E0405, E0425.
-For more information about an error, try `rustc --explain E0404`.
--- /dev/null
+// run-pass
+// ignore-test Not a test. Used by issue-48508.rs
+
+pub fn other() -> f64 {
+ let µ = 1.0;
+ µ
+}
--- /dev/null
+// run-pass
+// Regression test for issue #48508:
+//
+// Confusion between global and local file offsets caused incorrect handling of multibyte character
+// spans when compiling multiple files. One visible effect was an ICE generating debug information
+// when a multibyte character is at the end of a scope. The problematic code is actually in
+// issue-48508-aux.rs
+
+// compile-flags:-g
+// ignore-pretty issue #37195
+// ignore-asmjs wasm2js does not support source maps yet
+
+#![feature(non_ascii_idents)]
+#![allow(uncommon_codepoints)]
+
+#[path = "issue-48508-aux.rs"]
+mod other_file;
+
+fn main() {
+ other_file::other();
+}
--- /dev/null
+pub struct Foo {
+ pub bar: Vec<i32>ö
+ //~^ ERROR expected `,`, or `}`, found `ö`
+} //~ ERROR expected `:`, found `}`
+
+fn main() {}
--- /dev/null
+error: expected `,`, or `}`, found `ö`
+ --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:2:22
+ |
+LL | pub bar: Vec<i32>ö
+ | ^ help: try adding a comma: `,`
+
+error: expected `:`, found `}`
+ --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:4:1
+ |
+LL | pub bar: Vec<i32>ö
+ | - expected `:`
+LL |
+LL | }
+ | ^ unexpected token
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+// run-pass
+#![allow(unused_variables)]
+
+struct A { foo: isize }
+struct B { a: isize, b: isize, c: isize }
+
+fn mka() -> A { panic!() }
+fn mkb() -> B { panic!() }
+
+fn test() {
+ let A { foo, } = mka();
+ let A {
+ foo,
+ } = mka();
+
+ let B { a, b, c, } = mkb();
+
+ match mka() {
+ A { foo: _foo, } => {}
+ }
+
+ match Some(mka()) {
+ Some(A { foo: _foo, }) => {}
+ None => {}
+ }
+}
+
+pub fn main() {
+ if false { test() }
+}
struct Foo;
impl_macros!(Foo); //~ WARN using an old version
//~| WARN this was previously
- arrays!(Foo);
+ arrays!(Foo); //~ WARN using an old version
+ //~| WARN this was previously
other!(Foo);
}
tuple_from_req!(Foo);
}
+mod with_good_js_sys_version {
+ include!("js-sys-0.3.40/src/lib.rs");
+ struct Foo;
+ arrays!(Foo);
+}
+
fn main() {}
= note: 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
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+warning: using an old version of `js-sys`
+ --> $DIR/js-sys-0.3.17/src/lib.rs:5:32
+ |
+LL | #[my_macro] struct Two($name);
+ | ^^^^^
+ |
+ ::: $DIR/group-compat-hack.rs:46:5
+ |
+LL | arrays!(Foo);
+ | ------------- in this macro invocation
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+ = note: 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
+ = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
warning: using an old version of `actix-web`
--> $DIR/actix-web/src/extract.rs:5:34
|
LL | #[my_macro] struct Three($T);
| ^^
|
- ::: $DIR/group-compat-hack.rs:54:5
+ ::: $DIR/group-compat-hack.rs:55:5
|
LL | tuple_from_req!(Foo);
| --------------------- in this macro invocation
LL | #[my_macro] struct Three($T);
| ^^
|
- ::: $DIR/group-compat-hack.rs:62:5
+ ::: $DIR/group-compat-hack.rs:63:5
|
LL | tuple_from_req!(Foo);
| --------------------- in this macro invocation
= note: the version of `actix-web` you are using might stop compiling in future versions of Rust; please update to the latest version of the `actix-web` crate to avoid breakage
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-warning: 4 warnings emitted
+warning: 5 warnings emitted
Future incompatibility report: Future breakage date: None, diagnostic:
warning: using an old version of `time-macros-impl`
= note: 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
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+Future breakage date: None, diagnostic:
+warning: using an old version of `js-sys`
+ --> $DIR/js-sys-0.3.17/src/lib.rs:5:32
+ |
+LL | #[my_macro] struct Two($name);
+ | ^^^^^
+ |
+ ::: $DIR/group-compat-hack.rs:46:5
+ |
+LL | arrays!(Foo);
+ | ------------- in this macro invocation
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125>
+ = note: 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
+ = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
Future breakage date: None, diagnostic:
warning: using an old version of `actix-web`
--> $DIR/actix-web/src/extract.rs:5:34
LL | #[my_macro] struct Three($T);
| ^^
|
- ::: $DIR/group-compat-hack.rs:54:5
+ ::: $DIR/group-compat-hack.rs:55:5
|
LL | tuple_from_req!(Foo);
| --------------------- in this macro invocation
LL | #[my_macro] struct Three($T);
| ^^
|
- ::: $DIR/group-compat-hack.rs:62:5
+ ::: $DIR/group-compat-hack.rs:63:5
|
LL | tuple_from_req!(Foo);
| --------------------- in this macro invocation
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl/src/lib.rs:5:21: 5:27 (#6) }, Ident { ident: "One", span: $DIR/time-macros-impl/src/lib.rs:5:28: 5:31 (#6) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:27:18: 27:21 (#0) }], span: $DIR/time-macros-impl/src/lib.rs:5:31: 5:38 (#6) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl/src/lib.rs:5:38: 5:39 (#6) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys/src/lib.rs:5:21: 5:27 (#10) }, Ident { ident: "Two", span: $DIR/js-sys/src/lib.rs:5:28: 5:31 (#10) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:13: 29:16 (#0) }], span: $DIR/js-sys/src/lib.rs:5:31: 5:38 (#10) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys/src/lib.rs:5:38: 5:39 (#10) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys/src/lib.rs:5:21: 5:27 (#10) }, Ident { ident: "Two", span: $DIR/js-sys/src/lib.rs:5:28: 5:31 (#10) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:29:13: 29:16 (#0) }], span: $DIR/js-sys/src/lib.rs:5:32: 5:37 (#10) }], span: $DIR/js-sys/src/lib.rs:5:31: 5:38 (#10) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys/src/lib.rs:5:38: 5:39 (#10) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:22:25: 22:31 (#14) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:22:32: 22:37 (#14) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:30:12: 30:15 (#0) }], span: $DIR/group-compat-hack.rs:22:38: 22:43 (#14) }], span: $DIR/group-compat-hack.rs:22:37: 22:44 (#14) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:22:44: 22:45 (#14) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:21: 5:27 (#20) }, Ident { ident: "One", span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:28: 5:31 (#20) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:44:18: 44:21 (#0) }], span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:31: 5:38 (#20) }, Punct { ch: ';', spacing: Alone, span: $DIR/time-macros-impl-0.1.0/src/lib.rs:5:38: 5:39 (#20) }]
Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.17/src/lib.rs:5:21: 5:27 (#24) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.17/src/lib.rs:5:28: 5:31 (#24) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:46:13: 46:16 (#0) }], span: $DIR/js-sys-0.3.17/src/lib.rs:5:31: 5:38 (#24) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.17/src/lib.rs:5:38: 5:39 (#24) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:39:25: 39:31 (#28) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:39:32: 39:37 (#28) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:47:12: 47:15 (#0) }], span: $DIR/group-compat-hack.rs:39:38: 39:43 (#28) }], span: $DIR/group-compat-hack.rs:39:37: 39:44 (#28) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:39:44: 39:45 (#28) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web/src/extract.rs:5:21: 5:27 (#33) }, Ident { ident: "Three", span: $DIR/actix-web/src/extract.rs:5:28: 5:33 (#33) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:54:21: 54:24 (#0) }], span: $DIR/actix-web/src/extract.rs:5:33: 5:37 (#33) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web/src/extract.rs:5:37: 5:38 (#33) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web-2.0.0/src/extract.rs:5:21: 5:27 (#38) }, Ident { ident: "Three", span: $DIR/actix-web-2.0.0/src/extract.rs:5:28: 5:33 (#38) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:62:21: 62:24 (#0) }], span: $DIR/actix-web-2.0.0/src/extract.rs:5:33: 5:37 (#38) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web-2.0.0/src/extract.rs:5:37: 5:38 (#38) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web/src/extract.rs:5:21: 5:27 (#43) }, Ident { ident: "Four", span: $DIR/actori-web/src/extract.rs:5:28: 5:32 (#43) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:70:21: 70:24 (#0) }], span: $DIR/actori-web/src/extract.rs:5:33: 5:35 (#43) }], span: $DIR/actori-web/src/extract.rs:5:32: 5:36 (#43) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web/src/extract.rs:5:36: 5:37 (#43) }]
-Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web-2.0.0/src/extract.rs:5:21: 5:27 (#48) }, Ident { ident: "Four", span: $DIR/actori-web-2.0.0/src/extract.rs:5:28: 5:32 (#48) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:77:21: 77:24 (#0) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:33: 5:35 (#48) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:32: 5:36 (#48) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web-2.0.0/src/extract.rs:5:36: 5:37 (#48) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/group-compat-hack.rs:39:25: 39:31 (#28) }, Ident { ident: "Three", span: $DIR/group-compat-hack.rs:39:32: 39:37 (#28) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:48:12: 48:15 (#0) }], span: $DIR/group-compat-hack.rs:39:38: 39:43 (#28) }], span: $DIR/group-compat-hack.rs:39:37: 39:44 (#28) }, Punct { ch: ';', spacing: Alone, span: $DIR/group-compat-hack.rs:39:44: 39:45 (#28) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web/src/extract.rs:5:21: 5:27 (#33) }, Ident { ident: "Three", span: $DIR/actix-web/src/extract.rs:5:28: 5:33 (#33) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:55:21: 55:24 (#0) }], span: $DIR/actix-web/src/extract.rs:5:33: 5:37 (#33) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web/src/extract.rs:5:37: 5:38 (#33) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actix-web-2.0.0/src/extract.rs:5:21: 5:27 (#38) }, Ident { ident: "Three", span: $DIR/actix-web-2.0.0/src/extract.rs:5:28: 5:33 (#38) }, Group { delimiter: Parenthesis, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:63:21: 63:24 (#0) }], span: $DIR/actix-web-2.0.0/src/extract.rs:5:33: 5:37 (#38) }, Punct { ch: ';', spacing: Alone, span: $DIR/actix-web-2.0.0/src/extract.rs:5:37: 5:38 (#38) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web/src/extract.rs:5:21: 5:27 (#43) }, Ident { ident: "Four", span: $DIR/actori-web/src/extract.rs:5:28: 5:32 (#43) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:71:21: 71:24 (#0) }], span: $DIR/actori-web/src/extract.rs:5:33: 5:35 (#43) }], span: $DIR/actori-web/src/extract.rs:5:32: 5:36 (#43) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web/src/extract.rs:5:36: 5:37 (#43) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/actori-web-2.0.0/src/extract.rs:5:21: 5:27 (#48) }, Ident { ident: "Four", span: $DIR/actori-web-2.0.0/src/extract.rs:5:28: 5:32 (#48) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:78:21: 78:24 (#0) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:33: 5:35 (#48) }], span: $DIR/actori-web-2.0.0/src/extract.rs:5:32: 5:36 (#48) }, Punct { ch: ';', spacing: Alone, span: $DIR/actori-web-2.0.0/src/extract.rs:5:36: 5:37 (#48) }]
+Called proc_macro_hack with TokenStream [Ident { ident: "struct", span: $DIR/js-sys-0.3.40/src/lib.rs:5:21: 5:27 (#53) }, Ident { ident: "Two", span: $DIR/js-sys-0.3.40/src/lib.rs:5:28: 5:31 (#53) }, Group { delimiter: Parenthesis, stream: TokenStream [Group { delimiter: None, stream: TokenStream [Ident { ident: "Foo", span: $DIR/group-compat-hack.rs:84:13: 84:16 (#0) }], span: $DIR/js-sys-0.3.40/src/lib.rs:5:32: 5:37 (#53) }], span: $DIR/js-sys-0.3.40/src/lib.rs:5:31: 5:38 (#53) }, Punct { ch: ';', spacing: Alone, span: $DIR/js-sys-0.3.40/src/lib.rs:5:38: 5:39 (#53) }]
--- /dev/null
+// ignore-test this is not a test
+
+macro_rules! arrays {
+ ($name:ident) => {
+ #[my_macro] struct Two($name);
+ }
+}
--- /dev/null
+#![no_implicit_prelude]
+
+// Test that things from the prelude aren't in scope. Use many of them
+// so that renaming some things won't magically make this test fail
+// for the wrong reason (e.g., if `Add` changes to `Addition`, and
+// `no_implicit_prelude` stops working, then the `impl Add` will still
+// fail with the same error message).
+
+struct Test;
+impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope
+impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone`
+impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope
+impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope
+impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope
+
+fn main() {
+ drop(2) //~ ERROR cannot find function `drop` in this scope
+}
--- /dev/null
+error[E0405]: cannot find trait `Add` in this scope
+ --> $DIR/no-implicit-prelude.rs:10:6
+ |
+LL | impl Add for Test {}
+ | ^^^ not found in this scope
+ |
+help: consider importing this trait
+ |
+LL | use std::ops::Add;
+ |
+
+error[E0404]: expected trait, found derive macro `Clone`
+ --> $DIR/no-implicit-prelude.rs:11:6
+ |
+LL | impl Clone for Test {}
+ | ^^^^^ not a trait
+ |
+help: consider importing this trait instead
+ |
+LL | use std::clone::Clone;
+ |
+
+error[E0405]: cannot find trait `Iterator` in this scope
+ --> $DIR/no-implicit-prelude.rs:12:6
+ |
+LL | impl Iterator for Test {}
+ | ^^^^^^^^ not found in this scope
+ |
+help: consider importing this trait
+ |
+LL | use std::iter::Iterator;
+ |
+
+error[E0405]: cannot find trait `ToString` in this scope
+ --> $DIR/no-implicit-prelude.rs:13:6
+ |
+LL | impl ToString for Test {}
+ | ^^^^^^^^ not found in this scope
+ |
+help: consider importing this trait
+ |
+LL | use std::string::ToString;
+ |
+
+error[E0405]: cannot find trait `Writer` in this scope
+ --> $DIR/no-implicit-prelude.rs:14:6
+ |
+LL | impl Writer for Test {}
+ | ^^^^^^ not found in this scope
+
+error[E0425]: cannot find function `drop` in this scope
+ --> $DIR/no-implicit-prelude.rs:17:5
+ |
+LL | drop(2)
+ | ^^^^ not found in this scope
+ |
+help: consider importing this function
+ |
+LL | use std::mem::drop;
+ |
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0404, E0405, E0425.
+For more information about an error, try `rustc --explain E0404`.
+++ /dev/null
-// run-pass
-
-#![allow(non_camel_case_types)]
-#![allow(dead_code)]
-fn foo(c: Vec<isize> ) {
- let a: isize = 5;
- let mut b: Vec<isize> = Vec::new();
-
-
- match t::none::<isize> {
- t::some::<isize>(_) => {
- for _i in &c {
- println!("{}", a);
- let a = 17;
- b.push(a);
- }
- }
- _ => { }
- }
-}
-
-enum t<T> { none, some(T), }
-
-pub fn main() { let x = 10; let x = x + 20; assert_eq!(x, 30); foo(Vec::new()); }
--- /dev/null
+// run-pass
+#![allow(dead_code)]
+#![allow(non_camel_case_types)]
+
+
+enum pattern { tabby, tortoiseshell, calico }
+enum breed { beagle, rottweiler, pug }
+type name = String;
+enum ear_kind { lop, upright }
+enum animal { cat(pattern), dog(breed), rabbit(name, ear_kind), tiger }
+
+fn noise(a: animal) -> Option<String> {
+ match a {
+ animal::cat(..) => { Some("meow".to_string()) }
+ animal::dog(..) => { Some("woof".to_string()) }
+ animal::rabbit(..) => { None }
+ animal::tiger => { Some("roar".to_string()) }
+ }
+}
+
+pub fn main() {
+ assert_eq!(noise(animal::cat(pattern::tabby)), Some("meow".to_string()));
+ assert_eq!(noise(animal::dog(breed::pug)), Some("woof".to_string()));
+ assert_eq!(noise(animal::rabbit("Hilbert".to_string(), ear_kind::upright)), None);
+ assert_eq!(noise(animal::tiger), Some("roar".to_string()));
+}
--- /dev/null
+use std::ops::DispatchFromDyn; //~ ERROR use of unstable library feature 'dispatch_from_dyn'
+struct Smaht<T, MISC>(PhantomData); //~ ERROR cannot find type `PhantomData` in this scope
+impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {} //~ ERROR cannot find type `U` in this scope
+//~^ ERROR cannot find type `MISC` in this scope
+//~| ERROR use of unstable library feature 'dispatch_from_dyn'
+//~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures
+//~| ERROR type parameter `T` must be covered by another type when it appears before the first
+trait Foo: X<u32> {}
+trait X<T> {
+ fn foo(self: Smaht<Self, T>);
+}
+trait Marker {}
+impl Marker for dyn Foo {}
+fn main() {}
--- /dev/null
+error[E0412]: cannot find type `PhantomData` in this scope
+ --> $DIR/issue-78372.rs:2:23
+ |
+LL | struct Smaht<T, MISC>(PhantomData);
+ | ^^^^^^^^^^^ not found in this scope
+ |
+help: consider importing this struct
+ |
+LL | use std::marker::PhantomData;
+ |
+
+error[E0412]: cannot find type `U` in this scope
+ --> $DIR/issue-78372.rs:3:31
+ |
+LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
+ | - ^ help: a type parameter with a similar name exists: `T`
+ | |
+ | similarly named type parameter `T` defined here
+
+error[E0412]: cannot find type `MISC` in this scope
+ --> $DIR/issue-78372.rs:3:34
+ |
+LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
+ | - ^^^^ not found in this scope
+ | |
+ | help: you might be missing a type parameter: `, MISC`
+
+error[E0658]: use of unstable library feature 'dispatch_from_dyn'
+ --> $DIR/issue-78372.rs:1:5
+ |
+LL | use std::ops::DispatchFromDyn;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'dispatch_from_dyn'
+ --> $DIR/issue-78372.rs:3:9
+ |
+LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
+
+error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
+ --> $DIR/issue-78372.rs:3:1
+ |
+LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
+ --> $DIR/issue-78372.rs:3:6
+ |
+LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
+ | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
+ |
+ = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
+ = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0210, E0378, E0412, E0658.
+For more information about an error, try `rustc --explain E0210`.
--- /dev/null
+use std::mem::MaybeUninit;
+use std::ops::Deref;
+
+pub unsafe trait Array {
+ /// The array’s element type
+ type Item;
+ #[doc(hidden)]
+ /// The smallest index type that indexes the array.
+ type Index: Index;
+ #[doc(hidden)]
+ fn as_ptr(&self) -> *const Self::Item;
+ #[doc(hidden)]
+ fn as_mut_ptr(&mut self) -> *mut Self::Item;
+ #[doc(hidden)]
+ fn capacity() -> usize;
+}
+
+pub trait Index : PartialEq + Copy {
+ fn to_usize(self) -> usize;
+ fn from(usize) -> Self;
+}
+
+impl Index for usize {
+ fn to_usize(self) -> usize { self }
+ fn from(val: usize) -> Self {
+ val
+ }
+}
+
+unsafe impl<T> Array for [T; 1] {
+ type Item = T;
+ type Index = usize;
+ fn as_ptr(&self) -> *const T { self as *const _ as *const _ }
+ fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _}
+ fn capacity() -> usize { 1 }
+}
+
+impl<A: Array> Deref for ArrayVec<A> {
+ type Target = [A::Item];
+ #[inline]
+ fn deref(&self) -> &[A::Item] {
+ panic!()
+ }
+}
+
+pub struct ArrayVec<A: Array> {
+ xs: MaybeUninit<A>,
+ len: usize,
+}
+
+impl<A: Array> ArrayVec<A> {
+ pub fn new() -> ArrayVec<A> {
+ panic!()
+ }
+}
+
+fn main() {
+ let mut buffer = ArrayVec::new();
+ let x = buffer.last().unwrap().0.clone();
+ //~^ ERROR type annotations needed
+ //~| ERROR no field `0` on type `&_`
+ buffer.reverse();
+}
--- /dev/null
+error[E0282]: type annotations needed
+ --> $DIR/issue-65611.rs:59:20
+ |
+LL | let x = buffer.last().unwrap().0.clone();
+ | -------^^^^--
+ | | |
+ | | cannot infer type for type parameter `T`
+ | this method call resolves to `Option<&T>`
+ |
+ = note: type must be known at this point
+
+error[E0609]: no field `0` on type `&_`
+ --> $DIR/issue-65611.rs:59:36
+ |
+LL | let x = buffer.last().unwrap().0.clone();
+ | ^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0282, E0609.
+For more information about an error, try `rustc --explain E0282`.
let result = cx
.tcx
- .const_eval_resolve(cx.param_env, ty::WithOptConstParam::unknown(def_id), substs, None, None);
+ .const_eval_resolve(
+ cx.param_env,
+ ty::Unevaluated {
+ def: ty::WithOptConstParam::unknown(def_id),
+ substs,
+ promoted: None
+ },
+ None
+ );
is_value_unfrozen_raw(cx, result, ty)
}
.tcx
.const_eval_resolve(
self.param_env,
- ty::WithOptConstParam::unknown(def_id),
- substs,
- None,
+ ty::Unevaluated {
+ def: ty::WithOptConstParam::unknown(def_id),
+ substs,
+ promoted: None,
+ },
None,
)
.ok()
const ENTRY_LIMIT: usize = 1000;
// FIXME: The following limits should be reduced eventually.
-const ROOT_ENTRY_LIMIT: usize = 1408;
-const ISSUES_ENTRY_LIMIT: usize = 2565;
+const ROOT_ENTRY_LIMIT: usize = 1390;
+const ISSUES_ENTRY_LIMIT: usize = 2551;
fn check_entries(path: &Path, bad: &mut bool) {
let dirs = walkdir::WalkDir::new(&path.join("test/ui"))