]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #83339 - Aaron1011:deep-recollect, r=petrochenkov
authorbors <bors@rust-lang.org>
Sun, 21 Mar 2021 13:00:22 +0000 (13:00 +0000)
committerbors <bors@rust-lang.org>
Sun, 21 Mar 2021 13:00:22 +0000 (13:00 +0000)
Perform 'deep recollection' in test helper macros

Currently, the print helper macro performs 'recollection' by doing
`token_stream.into_iter().collect()`. However, this will not affect
nonterminals that occur nested inside delimited groups, since the
wrapping delimited group will be left untouched.

This commit adds 'deep recollection', which recursively recollects every
delimited group in the token stream. As with normal recollection, we
only print out something if deep recollection results in a different
stringified token stream.

This is useful for catching bugs where we update the AST of a
nonterminal (which affects pretty-printing), but do not update the
attatched `TokenStream`

123 files changed:
compiler/rustc_codegen_cranelift/src/constant.rs
compiler/rustc_codegen_ssa/src/mir/constant.rs
compiler/rustc_expand/src/proc_macro_server.rs
compiler/rustc_infer/src/infer/mod.rs
compiler/rustc_middle/src/mir/abstract_const.rs
compiler/rustc_middle/src/mir/interpret/queries.rs
compiler/rustc_middle/src/traits/mod.rs
compiler/rustc_middle/src/ty/consts.rs
compiler/rustc_middle/src/ty/consts/kind.rs
compiler/rustc_middle/src/ty/flags.rs
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_middle/src/ty/relate.rs
compiler/rustc_middle/src/ty/structural_impls.rs
compiler/rustc_middle/src/ty/walk.rs
compiler/rustc_mir/src/borrow_check/type_check/mod.rs
compiler/rustc_mir/src/interpret/operand.rs
compiler/rustc_mir/src/monomorphize/collector.rs
compiler/rustc_mir/src/monomorphize/polymorphize.rs
compiler/rustc_mir/src/transform/check_consts/qualifs.rs
compiler/rustc_mir/src/transform/const_prop.rs
compiler/rustc_mir/src/transform/inline.rs
compiler/rustc_mir/src/transform/promote_consts.rs
compiler/rustc_mir/src/transform/required_consts.rs
compiler/rustc_mir/src/transform/simplify.rs
compiler/rustc_mir_build/src/thir/cx/expr.rs
compiler/rustc_trait_selection/src/traits/auto_trait.rs
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
compiler/rustc_trait_selection/src/traits/fulfill.rs
compiler/rustc_trait_selection/src/traits/select/mod.rs
compiler/rustc_trait_selection/src/traits/wf.rs
compiler/rustc_typeck/src/collect.rs
library/std/src/keyword_docs.rs
src/librustdoc/clean/utils.rs
src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff
src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff
src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff
src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff
src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff
src/test/mir-opt/const_prop/ref_deref_project.main.PromoteTemps.diff
src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir
src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff
src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff
src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.32bit.diff
src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.64bit.diff
src/test/mir-opt/lower_intrinsics.discriminant.LowerIntrinsics.diff
src/test/mir-opt/match_false_edges.full_tested_match.PromoteTemps.after.mir
src/test/mir-opt/retag.main.SimplifyCfg-elaborate-drops.after.mir
src/test/ui/associated-types/issue-23208.rs [new file with mode: 0644]
src/test/ui/associated-types/issue-31597.rs [new file with mode: 0644]
src/test/ui/binding/shadow.rs [new file with mode: 0644]
src/test/ui/concat-rpass.rs [deleted file]
src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr
src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr
src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs [new file with mode: 0644]
src/test/ui/const_evaluatable/needs_where_clause.stderr
src/test/ui/const_evaluatable/no_where_clause.stderr
src/test/ui/consts/issue-52060.rs [new file with mode: 0644]
src/test/ui/consts/issue-52060.stderr [new file with mode: 0644]
src/test/ui/consts/mir_check_nonconst.rs [new file with mode: 0644]
src/test/ui/consts/mir_check_nonconst.stderr [new file with mode: 0644]
src/test/ui/fn_must_use.rs [deleted file]
src/test/ui/fn_must_use.stderr [deleted file]
src/test/ui/generator/issue-45729-unsafe-in-generator.rs [new file with mode: 0644]
src/test/ui/generator/issue-45729-unsafe-in-generator.stderr [new file with mode: 0644]
src/test/ui/impl-trait-in-bindings-issue-73003.rs [deleted file]
src/test/ui/impl-trait-in-bindings-issue-73003.stderr [deleted file]
src/test/ui/impl-trait-in-bindings.rs [deleted file]
src/test/ui/impl-trait-in-bindings.stderr [deleted file]
src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.rs [new file with mode: 0644]
src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.stderr [new file with mode: 0644]
src/test/ui/impl-trait/impl-trait-in-bindings.rs [new file with mode: 0644]
src/test/ui/impl-trait/impl-trait-in-bindings.stderr [new file with mode: 0644]
src/test/ui/issues/issue-10392.rs [deleted file]
src/test/ui/issues/issue-1701.rs [deleted file]
src/test/ui/issues/issue-23208.rs [deleted file]
src/test/ui/issues/issue-31597.rs [deleted file]
src/test/ui/issues/issue-45729-unsafe-in-generator.rs [deleted file]
src/test/ui/issues/issue-45729-unsafe-in-generator.stderr [deleted file]
src/test/ui/issues/issue-48508-aux.rs [deleted file]
src/test/ui/issues/issue-48508.rs [deleted file]
src/test/ui/issues/issue-52060.rs [deleted file]
src/test/ui/issues/issue-52060.stderr [deleted file]
src/test/ui/issues/issue-65611.rs [deleted file]
src/test/ui/issues/issue-65611.stderr [deleted file]
src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs [deleted file]
src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr [deleted file]
src/test/ui/issues/issue-78372.rs [deleted file]
src/test/ui/issues/issue-78372.stderr [deleted file]
src/test/ui/lint/fn_must_use.rs [new file with mode: 0644]
src/test/ui/lint/fn_must_use.stderr [new file with mode: 0644]
src/test/ui/macros/concat-rpass.rs [new file with mode: 0644]
src/test/ui/mir_check_nonconst.rs [deleted file]
src/test/ui/mir_check_nonconst.stderr [deleted file]
src/test/ui/no-implicit-prelude.rs [deleted file]
src/test/ui/no-implicit-prelude.stderr [deleted file]
src/test/ui/parser/issue-48508-aux.rs [new file with mode: 0644]
src/test/ui/parser/issue-48508.rs [new file with mode: 0644]
src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.rs [new file with mode: 0644]
src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.stderr [new file with mode: 0644]
src/test/ui/pattern/issue-10392.rs [new file with mode: 0644]
src/test/ui/proc-macro/group-compat-hack/group-compat-hack.rs
src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stderr
src/test/ui/proc-macro/group-compat-hack/group-compat-hack.stdout
src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.40/src/lib.rs [new file with mode: 0644]
src/test/ui/resolve/no-implicit-prelude.rs [new file with mode: 0644]
src/test/ui/resolve/no-implicit-prelude.stderr [new file with mode: 0644]
src/test/ui/shadow.rs [deleted file]
src/test/ui/structs-enums/issue-1701.rs [new file with mode: 0644]
src/test/ui/traits/issue-78372.rs [new file with mode: 0644]
src/test/ui/traits/issue-78372.stderr [new file with mode: 0644]
src/test/ui/typeck/issue-65611.rs [new file with mode: 0644]
src/test/ui/typeck/issue-65611.stderr [new file with mode: 0644]
src/tools/clippy/clippy_lints/src/non_copy_const.rs
src/tools/clippy/clippy_utils/src/consts.rs
src/tools/tidy/src/ui_tests.rs
src/version

index 9d93370b7d0c9d4dd88cf8ee8ce46cc0a1c2ee78..f4cbfb6967ff35bf92e5954adfcac45a0c0f8fbe 100644 (file)
@@ -45,9 +45,9 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool {
         };
         match const_.val {
             ConstKind::Value(_) => {}
-            ConstKind::Unevaluated(def, ref substs, promoted) => {
+            ConstKind::Unevaluated(unevaluated) => {
                 if let Err(err) =
-                    fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None)
+                    fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None)
                 {
                     all_constants_ok = false;
                     match err {
@@ -122,14 +122,14 @@ pub(crate) fn codegen_constant<'tcx>(
     };
     let const_val = match const_.val {
         ConstKind::Value(const_val) => const_val,
-        ConstKind::Unevaluated(def, ref substs, promoted) if fx.tcx.is_static(def.did) => {
+        ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => {
             assert!(substs.is_empty());
             assert!(promoted.is_none());
 
             return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx);
         }
-        ConstKind::Unevaluated(def, ref substs, promoted) => {
-            match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) {
+        ConstKind::Unevaluated(unevaluated) => {
+            match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
                 Ok(const_val) => const_val,
                 Err(_) => {
                     span_bug!(constant.span, "erroneous constant not captured by required_consts");
index aa41acc357841e0e58d78dc3df37a7236752cec0..fa8a53e60b169d96c4d25288556fbf29b15844ca 100644 (file)
@@ -30,10 +30,10 @@ pub fn eval_mir_constant(
             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
index cb41bc81225ec23bcbd83fe31027114a40e02924..1ea26b4eab44b3069ee73c8fcf0810a5016fe545 100644 (file)
@@ -739,9 +739,8 @@ fn ident_name_compatibility_hack(
 
                 let time_macros_impl =
                     macro_name == sym::impl_macros && matches_prefix("time-macros-impl", "lib.rs");
-                if time_macros_impl
-                    || (macro_name == sym::arrays && matches_prefix("js-sys", "lib.rs"))
-                {
+                let js_sys = macro_name == sym::arrays && matches_prefix("js-sys", "lib.rs");
+                if time_macros_impl || js_sys {
                     let snippet = source_map.span_to_snippet(orig_span);
                     if snippet.as_deref() == Ok("$name") {
                         if time_macros_impl {
@@ -754,8 +753,35 @@ fn ident_name_compatibility_hack(
                                 "the `time-macros-impl` crate will stop compiling in futures version of Rust. \
                                 Please update to the latest version of the `time` crate to avoid breakage".to_string())
                             );
+                            return Some((*ident, *is_raw));
+                        }
+                        if js_sys {
+                            if let Some(c) = path
+                                .components()
+                                .flat_map(|c| c.as_os_str().to_str())
+                                .find(|c| c.starts_with("js-sys"))
+                            {
+                                let mut version = c.trim_start_matches("js-sys-").split(".");
+                                if version.next() == Some("0")
+                                    && version.next() == Some("3")
+                                    && version
+                                        .next()
+                                        .and_then(|c| c.parse::<u32>().ok())
+                                        .map_or(false, |v| v < 40)
+                                {
+                                    rustc.sess.buffer_lint_with_diagnostic(
+                                        &PROC_MACRO_BACK_COMPAT,
+                                        orig_span,
+                                        ast::CRATE_NODE_ID,
+                                        "using an old version of `js-sys`",
+                                        BuiltinLintDiagnostics::ProcMacroBackCompat(
+                                        "older versions of the `js-sys` crate will stop compiling in future versions of Rust; \
+                                        please update to `js-sys` v0.3.40 or above".to_string())
+                                    );
+                                    return Some((*ident, *is_raw));
+                                }
+                            }
                         }
-                        return Some((*ident, *is_raw));
                     }
                 }
 
index 3df58cb7857f14125b869e14c0f8ed52a828bb4d..7b18f4d0ff6a976d6df51691592f775aaac1389d 100644 (file)
@@ -18,7 +18,6 @@
 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};
@@ -1499,9 +1498,7 @@ pub fn create_next_universe(&self) -> ty::UniverseIndex {
     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();
@@ -1510,7 +1507,7 @@ pub fn const_eval_resolve(
         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
index b85f1e6e5ded05aad2c176114f2a10245a3c7e13..776a777b1bdb5844c982a84be2dd39e94dbc5a0a 100644 (file)
@@ -18,3 +18,20 @@ pub enum Node<'tcx> {
     UnaryOp(mir::UnOp, NodeId),
     FunctionCall(NodeId, &'tcx [NodeId]),
 }
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
+pub enum NotConstEvaluatable {
+    Error(rustc_errors::ErrorReported),
+    MentionsInfer,
+    MentionsParam,
+}
+
+impl From<rustc_errors::ErrorReported> for NotConstEvaluatable {
+    fn from(e: rustc_errors::ErrorReported) -> NotConstEvaluatable {
+        NotConstEvaluatable::Error(e)
+    }
+}
+
+TrivialTypeFoldableAndLiftImpls! {
+    NotConstEvaluatable,
+}
index 3e7b93b32a6a5a2b08feeedac74a17c5d43a8c00..fa7c0670e8ce6a5c90c2ff9156cf3b4c513195a1 100644 (file)
@@ -1,7 +1,7 @@
 use super::{ErrorHandled, EvalToConstValueResult, GlobalId};
 
 use crate::mir;
-use crate::ty::subst::{InternalSubsts, SubstsRef};
+use crate::ty::subst::InternalSubsts;
 use crate::ty::{self, TyCtxt};
 use rustc_hir::def_id::DefId;
 use rustc_span::Span;
@@ -35,14 +35,12 @@ pub fn const_eval_poly(self, def_id: DefId) -> EvalToConstValueResult<'tcx> {
     pub fn const_eval_resolve(
         self,
         param_env: ty::ParamEnv<'tcx>,
-        def: ty::WithOptConstParam<DefId>,
-        substs: SubstsRef<'tcx>,
-        promoted: Option<mir::Promoted>,
+        ct: ty::Unevaluated<'tcx>,
         span: Option<Span>,
     ) -> EvalToConstValueResult<'tcx> {
-        match ty::Instance::resolve_opt_const_arg(self, param_env, def, substs) {
+        match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
             Ok(Some(instance)) => {
-                let cid = GlobalId { instance, promoted };
+                let cid = GlobalId { instance, promoted: ct.promoted };
                 self.const_eval_global_id(param_env, cid, span)
             }
             Ok(None) => Err(ErrorHandled::TooGeneric),
index 0bd0a701fb2e7aa2ebd2693130e377fe7ac0b858..90b82020551c27257c89c770593ff2e4edbc89cb 100644 (file)
@@ -9,7 +9,7 @@
 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};
 
@@ -398,7 +398,7 @@ pub enum SelectionError<'tcx> {
         ty::error::TypeError<'tcx>,
     ),
     TraitNotObjectSafe(DefId),
-    ConstEvalFailure(ErrorHandled),
+    NotConstEvaluatable(NotConstEvaluatable),
     Overflow,
 }
 
index 622f8e8ff6cce0781b7b54e880f0acf1f46fc6c5..779d6c90f973f022842b9bdd1b756525f9497676 100644 (file)
@@ -98,18 +98,18 @@ pub fn from_opt_const_arg_anon_const(
                 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 })
     }
index 43e22ce8f8731b632fdf903ca2610377ad0e3fb4..875d8d00a93d32b6686f786be497cf6b6040540b 100644 (file)
 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),
@@ -31,7 +39,7 @@ pub enum ConstKind<'tcx> {
 
     /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
     /// variants when the code is monomorphic enough for that.
-    Unevaluated(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>, Option<Promoted>),
+    Unevaluated(Unevaluated<'tcx>),
 
     /// Used to hold computed value.
     Value(ConstValue<'tcx>),
@@ -102,7 +110,7 @@ pub(super) fn try_eval(
         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`
@@ -132,7 +140,8 @@ pub(super) fn try_eval(
             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),
index 6ecd1ebf37039b3c0f3d8a6f26cddf89bad0b7a4..d6dc81c5b785d1093e4e3b8f3ea685e6e7b24c4c 100644 (file)
@@ -270,10 +270,7 @@ fn add_region(&mut self, r: ty::Region<'_>) {
     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 {
@@ -297,6 +294,11 @@ fn add_const(&mut self, c: &ty::Const<'_>) {
         }
     }
 
+    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);
index 5bbf7b35d3d74cb646bc0546b5f172ac0cfe3eea..e6b4739d0a2f55fdb37684696f882ed64ac82a15 100644 (file)
@@ -55,7 +55,7 @@
 
 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,
index 7946d170064c98b2061680dd05cc184d991b01c2..3b72cc011d6ea2253f6b7e138bd999dd3342018e 100644 (file)
@@ -915,7 +915,7 @@ macro_rules! print_underscore {
         }
 
         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));
index b41bf70e88eec973cc32c59958ae1f5a6d107e57..c936c30f456dd93736ea6c2c8010b1cc1106fa4d 100644 (file)
@@ -531,24 +531,26 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
             check_const_value_eq(relation, a_val, b_val, a, b)?
         }
 
-        (
-            ty::ConstKind::Unevaluated(a_def, a_substs, None),
-            ty::ConstKind::Unevaluated(b_def, b_substs, None),
-        ) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => {
-            tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs)))
+        (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
+            if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() =>
+        {
+            tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs)))
         }
 
         // While this is slightly incorrect, it shouldn't matter for `min_const_generics`
         // and is the better alternative to waiting until `const_evaluatable_checked` can
         // be stabilized.
-        (
-            ty::ConstKind::Unevaluated(a_def, a_substs, a_promoted),
-            ty::ConstKind::Unevaluated(b_def, b_substs, b_promoted),
-        ) if a_def == b_def && a_promoted == b_promoted => {
+        (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
+            if au.def == bu.def && au.promoted == bu.promoted =>
+        {
             let substs =
-                relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
+                relation.relate_with_variance(ty::Variance::Invariant, au.substs, bu.substs)?;
             return Ok(tcx.mk_const(ty::Const {
-                val: ty::ConstKind::Unevaluated(a_def, substs, a_promoted),
+                val: ty::ConstKind::Unevaluated(ty::Unevaluated {
+                    def: au.def,
+                    substs,
+                    promoted: au.promoted,
+                }),
                 ty: a.ty,
             }));
         }
index 0ca94a9f1805df88f78008c1e94081b5fd0ea688..2da23b331e0cb19a41e5e64d0664988ba1b344d1 100644 (file)
@@ -1031,8 +1031,12 @@ fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
         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(..)
@@ -1045,7 +1049,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow
         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(_)
index bb7fc661d2d8a193411b0c5e0609b35aea721c83..c2fe5f1ef3f625975eed1ae231d5a5dfa11c8cfe 100644 (file)
@@ -195,8 +195,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
                 | ty::ConstKind::Value(_)
                 | ty::ConstKind::Error(_) => {}
 
-                ty::ConstKind::Unevaluated(_, substs, _) => {
-                    stack.extend(substs.iter().rev());
+                ty::ConstKind::Unevaluated(ct) => {
+                    stack.extend(ct.substs.iter().rev());
                 }
             }
         }
index cce1549cb29c2fd47765cb9ecc595b47a7447c71..aaa2bf4ff1b50740f0a048c9d19ee5456cec64b7 100644 (file)
@@ -316,14 +316,12 @@ fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
             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>,
index 28933493a21c41bcfd271b194bbeda51bb6069fc..c70b57e631a80c6693d17f2c51b3bfea44adecfb 100644 (file)
@@ -560,7 +560,7 @@ pub(super) fn eval_operands(
         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())
             }
index 911224d8c1f445be9440f326bc5833feb1455d1f..e48640e1bb965720eb7848c422220f2a890cc350 100644 (file)
@@ -646,8 +646,8 @@ fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location)
 
         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!(
index 05b0e3a7dab954ba1114ff6a80736ae90c26ac4d..30e758c7fdf05f85502434243480faedac84a77a 100644 (file)
@@ -299,7 +299,7 @@ fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
                 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 =>
@@ -310,10 +310,10 @@ fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
                 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),
index 748f65cba2260b21f6de9ba07c6891aaee10138f..36644ab3c5918e4dda413a17055ef9e884155711 100644 (file)
@@ -247,7 +247,7 @@ pub fn in_operand<Q, F>(cx: &ConstCx<'_, 'tcx>, in_local: &mut F, operand: &Oper
 
     // 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() {
index cc8669d9705468ce65cba883b911a330a9f6df35..7706316c96516a3e3057837b58a32f31eb6cec9c 100644 (file)
@@ -491,7 +491,11 @@ fn eval_constant(&mut self, c: &Constant<'tcx>, source_info: SourceInfo) -> Opti
                     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(),
index 12fdbd6582e287e62de6f426b850cda61b1bb89e..b6f80763bc8c4c2b94b445b999a0d1bb85c2f3bb 100644 (file)
@@ -630,7 +630,7 @@ fn dest_needs_borrow(place: Place<'_>) -> bool {
                 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,
                         }
                     }),
index 7db790cf32b63bd3aea0a3d941f4415c4a91a3ed..c5a03f3a045b2fb1542e483cd3f9243e433b4574 100644 (file)
@@ -1001,17 +1001,17 @@ fn promote_candidate(
                     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(),
                 }))
index 2b518bd3a4813ca69680f590bbf75abd53ea7f81..8b64ad65ab35ca5ac000eb3c983ce0ea71d14adf 100644 (file)
@@ -15,7 +15,7 @@ pub fn new(required_consts: &'a mut Vec<Constant<'tcx>>) -> Self {
 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);
             }
         }
index d2314a9ba158a18f9a503321b494e86c63c3112a..3b074f9132fd95dfab58a7076b2abced7c7bcd74 100644 (file)
@@ -422,7 +422,9 @@ fn visit_lhs(&mut self, place: &Place<'tcx>, location: Location) {
             // 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),
index 200a5fc1043adf6251c2b1d28d1790277c3f79c9..9abee283160a47bd4fecaf87d550aad708bb0db3 100644 (file)
@@ -707,11 +707,11 @@ fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'thir,
                                 // 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 =
@@ -905,11 +905,11 @@ fn convert_path_expr(
                 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,
index 6510c9464e145d189544b0ae00b6ce1f8faadb3d..0d71fc57e394b00c0188c6ac582ee9a65b6e9eb6 100644 (file)
@@ -803,12 +803,10 @@ fn evaluate_nested_obligations(
                 }
                 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)),
index 670527fb3f08f1a7dfc0563bd18e757b5f3c7b8e..ac987a9f7b3848c2b37ca92ae60c7ade594648d9 100644 (file)
@@ -13,7 +13,7 @@
 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};
@@ -32,7 +32,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
     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;
@@ -103,29 +103,10 @@ enum FailureKind {
 
                 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
@@ -163,7 +144,11 @@ enum FailureKind {
     // 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) {
@@ -180,34 +165,16 @@ enum FailureKind {
 
     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(()),
     }
 }
 
@@ -239,7 +206,9 @@ pub fn from_const(
         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),
         }
@@ -532,22 +501,25 @@ fn build(mut self) -> Result<&'tcx [Node<'tcx>], ErrorReported> {
             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)))
     }
 }
 
@@ -673,10 +645,16 @@ pub(super) fn try_unify<'tcx>(
                 // 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.
index a3faf4cb7d4c19d1f2eb457087368fbcbfd56618..060e4e36dfefc5971b796d9233dc669d540de85d 100644 (file)
@@ -2,10 +2,10 @@
 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};
@@ -17,7 +17,7 @@
 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::{
@@ -738,24 +738,59 @@ fn report_selection_error(
                 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");
             }
index 7d451fc234106e7d966623763a671144d19bb69a..79f65669479c880ec27d0d7895415db6c54c022b 100644 (file)
@@ -3,7 +3,8 @@
 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;
@@ -18,7 +19,7 @@
 use super::CodeAmbiguity;
 use super::CodeProjectionError;
 use super::CodeSelectionError;
-use super::{ConstEvalFailure, Unimplemented};
+use super::Unimplemented;
 use super::{FulfillmentError, FulfillmentErrorCode};
 use super::{ObligationCause, PredicateObligation};
 
@@ -498,14 +499,19 @@ fn progress_changed_obligations(
                         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),
+                        )),
                     }
                 }
 
@@ -516,15 +522,13 @@ fn progress_changed_obligations(
                         // 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![]);
                             }
@@ -534,18 +538,17 @@ fn progress_changed_obligations(
                     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),
                                     );
@@ -576,11 +579,11 @@ fn progress_changed_obligations(
                             }
                         }
                         (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()),
index 45b5aff40a6d277b6c1bbf14497c4850451922cd..bc0f0d6dea5da3a4d85d40414f7eb6f4b076a6ec 100644 (file)
@@ -34,6 +34,7 @@
 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;
@@ -547,7 +548,8 @@ fn evaluate_predicate_recursively<'o>(
                         obligation.cause.span,
                     ) {
                         Ok(()) => Ok(EvaluatedToOk),
-                        Err(ErrorHandled::TooGeneric) => Ok(EvaluatedToAmbig),
+                        Err(NotConstEvaluatable::MentionsInfer) => Ok(EvaluatedToAmbig),
+                        Err(NotConstEvaluatable::MentionsParam) => Ok(EvaluatedToErr),
                         Err(_) => Ok(EvaluatedToErr),
                     }
                 }
@@ -556,13 +558,11 @@ fn evaluate_predicate_recursively<'o>(
                     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))
index e6ef9b137d89991f56f6b2722e0e36f8c2e5cd28..aee128dec7d12b430f86103416691fda55ead933 100644 (file)
@@ -430,7 +430,7 @@ fn compute(&mut self, arg: GenericArg<'tcx>) {
 
                 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);
index e5136355ca9822ad553bfd1ad1b3468a39c5acdb..162fccc6020365b0fa51abef9cc9f5793d2407f4 100644 (file)
@@ -2212,10 +2212,11 @@ fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
         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,
                 ));
             }
index 383eaf2e3a206db4b21e72bd4940ce43e2b0e8c2..e64cbc18bf71b09ef9cca97a767750a3487148ed 100644 (file)
@@ -1031,8 +1031,8 @@ mod mod_keyword {}
 /// };
 /// ```
 ///
-/// 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
index 8b5f5b66c45fc1480117695325d4cb34779b775c..6f283d501a4f2d71e28e679a6d004bcce82947a1 100644 (file)
@@ -296,7 +296,7 @@ fn to_src(&self, cx: &DocContext<'_>) -> String {
 
 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))
index 5ba76c4f0bd70906101943976df344f1499bff62..4e990dd6b705efb17e18b3cb34e42262421823aa 100644 (file)
@@ -22,7 +22,7 @@
 -                                          // + 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)) }
@@ -30,7 +30,7 @@
 -         _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
index 1565cc7d5e72f776f5e1c1bb314325138b1cf56d..0a9a3f3c2c5f668e680e2aaa5c9b683948061132 100644 (file)
@@ -24,7 +24,7 @@
 -                                          // + 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)) }
@@ -32,7 +32,7 @@
 -         _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
index 8c10b3518d8c859e944b5d1cba6e8e10338be4fa..baa8988f1526332a3d56e4c5011a854d3c64db2b 100644 (file)
           _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
index 8c10b3518d8c859e944b5d1cba6e8e10338be4fa..baa8988f1526332a3d56e4c5011a854d3c64db2b 100644 (file)
           _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
index 6034645864656af9de38ce46e792c1b28cf48857..8ba11df7e0edddfa77e2cc5fe4ffeeb1dcd447cf 100644 (file)
           _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
index 4fd1b8b2276496da04fbbff47073b6ba27f79122..56683d7ef037c7699ee9980df97fcb7f4f4db841 100644 (file)
           _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
index e7ebfee7f3e013dfb5cc5a4c4a182f552a7dae7c..e1c8085b31b4f034fe689365dff1bbd7ede72b88 100644 (file)
 +         _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
index 812c7c9771801d5809b7c9a89eff69fc76f922cc..cce4831b6fe829b8fdea1cd5be3a340493312f9c 100644 (file)
           _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
index 588c291bcc37a1bf0a39db45f400dc1f50a1ff3c..93ba9de8202400526c838168d23c7d64c725b4dd 100644 (file)
 +         _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
index 240cc8e231168b14e82b3d8b7b399c983384a368..20f93f874c539a40cdce2176403d1dad1ca33399 100644 (file)
           _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
index 240cc8e231168b14e82b3d8b7b399c983384a368..20f93f874c539a40cdce2176403d1dad1ca33399 100644 (file)
           _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
index b9fe84fcd0443e70bf304ec79fb35816d9d7c459..0b5dc2b20fc98155fe3c68bd63ea38bfeac8205a 100644 (file)
@@ -35,10 +35,10 @@ fn bar() -> bool {
         _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
@@ -49,10 +49,10 @@ fn bar() -> bool {
         _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
index f6e6614bb6eceea25cbeda7585439102d9d1bf92..1ba56016776364fbced9aa017fa032ecd2cabd19 100644 (file)
           _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
index f6e6614bb6eceea25cbeda7585439102d9d1bf92..1ba56016776364fbced9aa017fa032ecd2cabd19 100644 (file)
           _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
index bd24522271b933dafefba30ecef067140fc43b14..5ae26b73a654800986f4cec6965870f70f39e11e 100644 (file)
           _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
index bd24522271b933dafefba30ecef067140fc43b14..5ae26b73a654800986f4cec6965870f70f39e11e 100644 (file)
           _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
index 7da2ff02006bf8f4055ba5ff956d036ecafb8ef5..83650d837b01bd0e5d3a00bf15241cf7fe7c809d 100644 (file)
           _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
index 2332e5beafe0f38d71a8bbd0d7177e5cd45d8784..242138754c5d74359e43d669fdcbe8d6daf5a8d0 100644 (file)
@@ -54,10 +54,10 @@ fn full_tested_match() -> () {
         _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
index 8c7d79262b242438cc898d7015ddbdbf3cf3ce62..d25f98db9f66278c5066e3f8f17e0858edd9fb18 100644 (file)
@@ -149,10 +149,10 @@ fn main() -> () {
         _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
diff --git a/src/test/ui/associated-types/issue-23208.rs b/src/test/ui/associated-types/issue-23208.rs
new file mode 100644 (file)
index 0000000..fd4ffe5
--- /dev/null
@@ -0,0 +1,26 @@
+// 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);
+}
diff --git a/src/test/ui/associated-types/issue-31597.rs b/src/test/ui/associated-types/issue-31597.rs
new file mode 100644 (file)
index 0000000..2872be6
--- /dev/null
@@ -0,0 +1,29 @@
+// 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() {}
diff --git a/src/test/ui/binding/shadow.rs b/src/test/ui/binding/shadow.rs
new file mode 100644 (file)
index 0000000..2495c8f
--- /dev/null
@@ -0,0 +1,24 @@
+// 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()); }
diff --git a/src/test/ui/concat-rpass.rs b/src/test/ui/concat-rpass.rs
deleted file mode 100644 (file)
index 0c30a39..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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
-    })
-}
index 1beb5315d1055615ad0a7c49abd1d801422211b8..84b2665d5bfeddb5d3f7183686267c0efae32ce6 100644 (file)
@@ -3,48 +3,52 @@ error: unconstrained generic constant
    |
 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
 
index 8cdc9b57750ee35f1a4c0861fe1173d69856948d..7c11a47b2f0f9ca983373428de6f9ad032f45f60 100644 (file)
@@ -4,11 +4,7 @@ error: unconstrained generic constant
 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
 
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs b/src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs
new file mode 100644 (file)
index 0000000..92a410a
--- /dev/null
@@ -0,0 +1,17 @@
+// 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() {}
index 945105d1a2dc6180c1643418f6adcfc16c81be8f..7b41e39b7d742d96c3226abe5ebec8bfd617e917 100644 (file)
@@ -4,11 +4,7 @@ error: unconstrained generic constant
 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
 
index 84a65f0d1d29bd8bdcda5a688ddc2cfbc2855ed0..3e5c2f5cad1dfff3a3c08fc5bea2310d7b7618fb 100644 (file)
@@ -4,11 +4,7 @@ error: unconstrained generic constant
 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
 
diff --git a/src/test/ui/consts/issue-52060.rs b/src/test/ui/consts/issue-52060.rs
new file mode 100644 (file)
index 0000000..13b914c
--- /dev/null
@@ -0,0 +1,7 @@
+// 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() {}
diff --git a/src/test/ui/consts/issue-52060.stderr b/src/test/ui/consts/issue-52060.stderr
new file mode 100644 (file)
index 0000000..95e5f2a
--- /dev/null
@@ -0,0 +1,11 @@
+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`.
diff --git a/src/test/ui/consts/mir_check_nonconst.rs b/src/test/ui/consts/mir_check_nonconst.rs
new file mode 100644 (file)
index 0000000..b8ec0c3
--- /dev/null
@@ -0,0 +1,11 @@
+#![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() {}
diff --git a/src/test/ui/consts/mir_check_nonconst.stderr b/src/test/ui/consts/mir_check_nonconst.stderr
new file mode 100644 (file)
index 0000000..30f68ba
--- /dev/null
@@ -0,0 +1,9 @@
+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`.
diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/fn_must_use.rs
deleted file mode 100644 (file)
index b4e9da0..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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
-}
diff --git a/src/test/ui/fn_must_use.stderr b/src/test/ui/fn_must_use.stderr
deleted file mode 100644 (file)
index d6b1cf3..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-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
-
diff --git a/src/test/ui/generator/issue-45729-unsafe-in-generator.rs b/src/test/ui/generator/issue-45729-unsafe-in-generator.rs
new file mode 100644 (file)
index 0000000..638a199
--- /dev/null
@@ -0,0 +1,9 @@
+#![feature(generators)]
+
+fn main() {
+    let _ = || {
+        *(1 as *mut u32) = 42;
+        //~^ ERROR dereference of raw pointer is unsafe
+        yield;
+    };
+}
diff --git a/src/test/ui/generator/issue-45729-unsafe-in-generator.stderr b/src/test/ui/generator/issue-45729-unsafe-in-generator.stderr
new file mode 100644 (file)
index 0000000..2aab680
--- /dev/null
@@ -0,0 +1,11 @@
+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`.
diff --git a/src/test/ui/impl-trait-in-bindings-issue-73003.rs b/src/test/ui/impl-trait-in-bindings-issue-73003.rs
deleted file mode 100644 (file)
index fd8fe5f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// check-pass
-
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-const _: impl Fn() = ||();
-
-fn main() {}
diff --git a/src/test/ui/impl-trait-in-bindings-issue-73003.stderr b/src/test/ui/impl-trait-in-bindings-issue-73003.stderr
deleted file mode 100644 (file)
index 715671c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
-
diff --git a/src/test/ui/impl-trait-in-bindings.rs b/src/test/ui/impl-trait-in-bindings.rs
deleted file mode 100644 (file)
index c7fae45..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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);
-}
diff --git a/src/test/ui/impl-trait-in-bindings.stderr b/src/test/ui/impl-trait-in-bindings.stderr
deleted file mode 100644 (file)
index bf739d4..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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
-
diff --git a/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.rs b/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.rs
new file mode 100644 (file)
index 0000000..fd8fe5f
--- /dev/null
@@ -0,0 +1,8 @@
+// check-pass
+
+#![feature(impl_trait_in_bindings)]
+//~^ WARN the feature `impl_trait_in_bindings` is incomplete
+
+const _: impl Fn() = ||();
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.stderr b/src/test/ui/impl-trait/impl-trait-in-bindings-issue-73003.stderr
new file mode 100644 (file)
index 0000000..715671c
--- /dev/null
@@ -0,0 +1,11 @@
+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
+
diff --git a/src/test/ui/impl-trait/impl-trait-in-bindings.rs b/src/test/ui/impl-trait/impl-trait-in-bindings.rs
new file mode 100644 (file)
index 0000000..c7fae45
--- /dev/null
@@ -0,0 +1,49 @@
+// 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);
+}
diff --git a/src/test/ui/impl-trait/impl-trait-in-bindings.stderr b/src/test/ui/impl-trait/impl-trait-in-bindings.stderr
new file mode 100644 (file)
index 0000000..bf739d4
--- /dev/null
@@ -0,0 +1,11 @@
+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
+
diff --git a/src/test/ui/issues/issue-10392.rs b/src/test/ui/issues/issue-10392.rs
deleted file mode 100644 (file)
index 926fa94..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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() }
-}
diff --git a/src/test/ui/issues/issue-1701.rs b/src/test/ui/issues/issue-1701.rs
deleted file mode 100644 (file)
index bae32a7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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()));
-}
diff --git a/src/test/ui/issues/issue-23208.rs b/src/test/ui/issues/issue-23208.rs
deleted file mode 100644 (file)
index fd4ffe5..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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);
-}
diff --git a/src/test/ui/issues/issue-31597.rs b/src/test/ui/issues/issue-31597.rs
deleted file mode 100644 (file)
index 2872be6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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() {}
diff --git a/src/test/ui/issues/issue-45729-unsafe-in-generator.rs b/src/test/ui/issues/issue-45729-unsafe-in-generator.rs
deleted file mode 100644 (file)
index 638a199..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#![feature(generators)]
-
-fn main() {
-    let _ = || {
-        *(1 as *mut u32) = 42;
-        //~^ ERROR dereference of raw pointer is unsafe
-        yield;
-    };
-}
diff --git a/src/test/ui/issues/issue-45729-unsafe-in-generator.stderr b/src/test/ui/issues/issue-45729-unsafe-in-generator.stderr
deleted file mode 100644 (file)
index 2aab680..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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`.
diff --git a/src/test/ui/issues/issue-48508-aux.rs b/src/test/ui/issues/issue-48508-aux.rs
deleted file mode 100644 (file)
index ebdc70a..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// run-pass
-// ignore-test Not a test. Used by issue-48508.rs
-
-pub fn other() -> f64 {
-    let µ = 1.0;
-    µ
-}
diff --git a/src/test/ui/issues/issue-48508.rs b/src/test/ui/issues/issue-48508.rs
deleted file mode 100644 (file)
index 8dc9351..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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();
-}
diff --git a/src/test/ui/issues/issue-52060.rs b/src/test/ui/issues/issue-52060.rs
deleted file mode 100644 (file)
index 13b914c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// 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() {}
diff --git a/src/test/ui/issues/issue-52060.stderr b/src/test/ui/issues/issue-52060.stderr
deleted file mode 100644 (file)
index 95e5f2a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-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`.
diff --git a/src/test/ui/issues/issue-65611.rs b/src/test/ui/issues/issue-65611.rs
deleted file mode 100644 (file)
index b74ee1b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-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();
-}
diff --git a/src/test/ui/issues/issue-65611.stderr b/src/test/ui/issues/issue-65611.stderr
deleted file mode 100644 (file)
index e3c005a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-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`.
diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs
deleted file mode 100644 (file)
index 3c49a5a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-pub struct Foo {
-    pub bar: Vec<i32>ö
-    //~^ ERROR expected `,`, or `}`, found `ö`
-} //~ ERROR expected `:`, found `}`
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr
deleted file mode 100644 (file)
index ef365a6..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-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
-
diff --git a/src/test/ui/issues/issue-78372.rs b/src/test/ui/issues/issue-78372.rs
deleted file mode 100644 (file)
index 77a8c92..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-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() {}
diff --git a/src/test/ui/issues/issue-78372.stderr b/src/test/ui/issues/issue-78372.stderr
deleted file mode 100644 (file)
index 9267e83..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-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`.
diff --git a/src/test/ui/lint/fn_must_use.rs b/src/test/ui/lint/fn_must_use.rs
new file mode 100644 (file)
index 0000000..b4e9da0
--- /dev/null
@@ -0,0 +1,76 @@
+// 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
+}
diff --git a/src/test/ui/lint/fn_must_use.stderr b/src/test/ui/lint/fn_must_use.stderr
new file mode 100644 (file)
index 0000000..d6b1cf3
--- /dev/null
@@ -0,0 +1,59 @@
+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
+
diff --git a/src/test/ui/macros/concat-rpass.rs b/src/test/ui/macros/concat-rpass.rs
new file mode 100644 (file)
index 0000000..0c30a39
--- /dev/null
@@ -0,0 +1,18 @@
+// 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
+    })
+}
diff --git a/src/test/ui/mir_check_nonconst.rs b/src/test/ui/mir_check_nonconst.rs
deleted file mode 100644 (file)
index b8ec0c3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#![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() {}
diff --git a/src/test/ui/mir_check_nonconst.stderr b/src/test/ui/mir_check_nonconst.stderr
deleted file mode 100644 (file)
index 30f68ba..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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`.
diff --git a/src/test/ui/no-implicit-prelude.rs b/src/test/ui/no-implicit-prelude.rs
deleted file mode 100644 (file)
index 4b0ca4d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#![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
-}
diff --git a/src/test/ui/no-implicit-prelude.stderr b/src/test/ui/no-implicit-prelude.stderr
deleted file mode 100644 (file)
index 36a9b65..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-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`.
diff --git a/src/test/ui/parser/issue-48508-aux.rs b/src/test/ui/parser/issue-48508-aux.rs
new file mode 100644 (file)
index 0000000..ebdc70a
--- /dev/null
@@ -0,0 +1,7 @@
+// run-pass
+// ignore-test Not a test. Used by issue-48508.rs
+
+pub fn other() -> f64 {
+    let µ = 1.0;
+    µ
+}
diff --git a/src/test/ui/parser/issue-48508.rs b/src/test/ui/parser/issue-48508.rs
new file mode 100644 (file)
index 0000000..8dc9351
--- /dev/null
@@ -0,0 +1,21 @@
+// 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();
+}
diff --git a/src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.rs b/src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.rs
new file mode 100644 (file)
index 0000000..3c49a5a
--- /dev/null
@@ -0,0 +1,6 @@
+pub struct Foo {
+    pub bar: Vec<i32>ö
+    //~^ ERROR expected `,`, or `}`, found `ö`
+} //~ ERROR expected `:`, found `}`
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.stderr b/src/test/ui/parser/issue-68000-unicode-ident-after-missing-comma.stderr
new file mode 100644 (file)
index 0000000..ef365a6
--- /dev/null
@@ -0,0 +1,17 @@
+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
+
diff --git a/src/test/ui/pattern/issue-10392.rs b/src/test/ui/pattern/issue-10392.rs
new file mode 100644 (file)
index 0000000..926fa94
--- /dev/null
@@ -0,0 +1,30 @@
+// 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() }
+}
index d9687490cad7598e8465efc149edef40c7819e09..2b742771d6f2c7dede3574c71e7577bdd4747a5d 100644 (file)
@@ -43,7 +43,8 @@ macro_rules! other {
     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);
 }
 
@@ -77,5 +78,11 @@ mod actori_web_version_test {
     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() {}
index e2b680f8d27600e9d3b1ee992a51d6d7f171b9b1..effcd68cf967c9fe331b3d9fb3cf3b029b8ebe92 100644 (file)
@@ -31,13 +31,29 @@ LL |     impl_macros!(Foo);
    = 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
@@ -53,7 +69,7 @@ warning: using an old version of `actix-web`
 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
@@ -63,7 +79,7 @@ LL |     tuple_from_req!(Foo);
    = 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`
@@ -100,6 +116,23 @@ LL |     impl_macros!(Foo);
    = 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
@@ -107,7 +140,7 @@ warning: using an old version of `actix-web`
 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
@@ -124,7 +157,7 @@ warning: using an old version of `actix-web`
 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
index 3fe744e12ff0459a2df04c4e60913abb5508f3dd..82d6bc33bf95b95f960d75d2bd360dcb3d54373c 100644 (file)
@@ -1,10 +1,11 @@
 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) }]
diff --git a/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.40/src/lib.rs b/src/test/ui/proc-macro/group-compat-hack/js-sys-0.3.40/src/lib.rs
new file mode 100644 (file)
index 0000000..d1a6694
--- /dev/null
@@ -0,0 +1,7 @@
+// ignore-test this is not a test
+
+macro_rules! arrays {
+    ($name:ident) => {
+        #[my_macro] struct Two($name);
+    }
+}
diff --git a/src/test/ui/resolve/no-implicit-prelude.rs b/src/test/ui/resolve/no-implicit-prelude.rs
new file mode 100644 (file)
index 0000000..4b0ca4d
--- /dev/null
@@ -0,0 +1,18 @@
+#![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
+}
diff --git a/src/test/ui/resolve/no-implicit-prelude.stderr b/src/test/ui/resolve/no-implicit-prelude.stderr
new file mode 100644 (file)
index 0000000..36a9b65
--- /dev/null
@@ -0,0 +1,65 @@
+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`.
diff --git a/src/test/ui/shadow.rs b/src/test/ui/shadow.rs
deleted file mode 100644 (file)
index 2495c8f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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()); }
diff --git a/src/test/ui/structs-enums/issue-1701.rs b/src/test/ui/structs-enums/issue-1701.rs
new file mode 100644 (file)
index 0000000..bae32a7
--- /dev/null
@@ -0,0 +1,26 @@
+// 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()));
+}
diff --git a/src/test/ui/traits/issue-78372.rs b/src/test/ui/traits/issue-78372.rs
new file mode 100644 (file)
index 0000000..77a8c92
--- /dev/null
@@ -0,0 +1,14 @@
+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() {}
diff --git a/src/test/ui/traits/issue-78372.stderr b/src/test/ui/traits/issue-78372.stderr
new file mode 100644 (file)
index 0000000..9267e83
--- /dev/null
@@ -0,0 +1,62 @@
+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`.
diff --git a/src/test/ui/typeck/issue-65611.rs b/src/test/ui/typeck/issue-65611.rs
new file mode 100644 (file)
index 0000000..b74ee1b
--- /dev/null
@@ -0,0 +1,63 @@
+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();
+}
diff --git a/src/test/ui/typeck/issue-65611.stderr b/src/test/ui/typeck/issue-65611.stderr
new file mode 100644 (file)
index 0000000..e3c005a
--- /dev/null
@@ -0,0 +1,21 @@
+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`.
index 8aebce67917afa1559e16925ced20f8f16238bf7..3e1db233696fe50042b6c80d040cb3059829a190 100644 (file)
@@ -181,7 +181,15 @@ fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: D
 
     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)
 }
 
index 802c01055a68c84d68dd4307c841c6b67bcfa334..ebe896b7ae86771c13ecabf27d3434a7d53ec6e0 100644 (file)
@@ -341,9 +341,11 @@ fn fetch_path(&mut self, qpath: &QPath<'_>, id: HirId, ty: Ty<'tcx>) -> Option<C
                     .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()
index 3374a8c9b73fac35952b9d9a992b58b4fefa1c96..7cc660454b492b6719d7f72a3f7eff6869cdc6fe 100644 (file)
@@ -7,8 +7,8 @@
 
 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"))
index a63cb35e6f0b4bda4987647fd5dca37de7b43f49..3f4830156cbef3adc811557eb7eb6f9d13906407 100644 (file)
@@ -1 +1 @@
-1.52.0
+1.53.0