]> git.lizzy.rs Git - rust.git/commitdiff
Evaluate repeat expression lengths as late as possible
authorOliver Scherer <github35764891676564198441@oli-obk.de>
Sat, 14 Mar 2020 14:30:35 +0000 (15:30 +0100)
committerOliver Scherer <github35764891676564198441@oli-obk.de>
Mon, 23 Mar 2020 12:14:36 +0000 (13:14 +0100)
46 files changed:
src/librustc/mir/mod.rs
src/librustc/mir/tcx.rs
src/librustc/ty/sty.rs
src/librustc_codegen_ssa/mir/rvalue.rs
src/librustc_mir/borrow_check/type_check/mod.rs
src/librustc_mir_build/hair/cx/expr.rs
src/librustc_mir_build/hair/mod.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/expr.rs
src/librustc_typeck/check/mod.rs
src/test/compile-fail/issue-52443.rs
src/test/ui/closures/issue-52437.rs
src/test/ui/closures/issue-52437.stderr
src/test/ui/const-generics/issues/issue-61336-1.rs
src/test/ui/const-generics/issues/issue-61336-1.stderr
src/test/ui/const-generics/issues/issue-61336-2.rs
src/test/ui/const-generics/issues/issue-61336-2.stderr
src/test/ui/const-generics/issues/issue-61336.rs
src/test/ui/const-generics/issues/issue-61336.stderr
src/test/ui/const-generics/issues/issue-62456.rs
src/test/ui/const-generics/issues/issue-62456.stderr
src/test/ui/const-generics/issues/issue-62504.rs
src/test/ui/const-generics/issues/issue-62504.stderr
src/test/ui/const-generics/issues/issue-67739.rs
src/test/ui/const-generics/issues/issue-67739.stderr [deleted file]
src/test/ui/consts/const-eval/const-eval-overflow-3.rs
src/test/ui/consts/const-eval/const-eval-overflow-3.stderr
src/test/ui/consts/const-eval/const-eval-overflow-3b.rs
src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
src/test/ui/consts/const-eval/issue-52442.rs
src/test/ui/consts/const-eval/issue-52442.stderr
src/test/ui/consts/const-eval/match-test-ptr-null.rs
src/test/ui/consts/const-eval/match-test-ptr-null.stderr
src/test/ui/consts/issue-52432.rs
src/test/ui/consts/issue-52432.stderr
src/test/ui/consts/too_generic_eval_ice.rs
src/test/ui/consts/too_generic_eval_ice.stderr
src/test/ui/issues/issue-39559-2.rs
src/test/ui/issues/issue-39559-2.stderr
src/test/ui/issues/issue-52060.rs
src/test/ui/issues/issue-52060.stderr
src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
src/test/ui/repeat_count.stderr
src/test/ui/resolve/issue-65035-static-with-parent-generics.rs
src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr

index 9018cd2656f9fb1836217b43d4653ce65a00e874..d81b940cbe797c6891ad1b05a65b28ec1a5ab61d 100644 (file)
@@ -2066,7 +2066,7 @@ pub enum Rvalue<'tcx> {
     Use(Operand<'tcx>),
 
     /// [x; 32]
-    Repeat(Operand<'tcx>, u64),
+    Repeat(Operand<'tcx>, &'tcx ty::Const<'tcx>),
 
     /// &x or &mut x
     Ref(Region<'tcx>, BorrowKind, Place<'tcx>),
@@ -2194,7 +2194,11 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
 
         match *self {
             Use(ref place) => write!(fmt, "{:?}", place),
-            Repeat(ref a, ref b) => write!(fmt, "[{:?}; {:?}]", a, b),
+            Repeat(ref a, ref b) => {
+                write!(fmt, "[{:?}; ", a)?;
+                pretty_print_const(b, fmt, false)?;
+                write!(fmt, "]")
+            }
             Len(ref a) => write!(fmt, "Len({:?})", a),
             Cast(ref kind, ref place, ref ty) => {
                 write!(fmt, "{:?} as {:?} ({:?})", place, ty, kind)
@@ -2562,18 +2566,26 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
 
 impl<'tcx> Display for Constant<'tcx> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        use crate::ty::print::PrettyPrinter;
         write!(fmt, "const ")?;
-        ty::tls::with(|tcx| {
-            let literal = tcx.lift(&self.literal).unwrap();
-            let mut cx = FmtPrinter::new(tcx, fmt, Namespace::ValueNS);
-            cx.print_alloc_ids = true;
-            cx.pretty_print_const(literal, true)?;
-            Ok(())
-        })
+        pretty_print_const(self.literal, fmt, true)
     }
 }
 
+fn pretty_print_const(
+    c: &ty::Const<'tcx>,
+    fmt: &mut Formatter<'_>,
+    print_types: bool,
+) -> fmt::Result {
+    use crate::ty::print::PrettyPrinter;
+    ty::tls::with(|tcx| {
+        let literal = tcx.lift(&c).unwrap();
+        let mut cx = FmtPrinter::new(tcx, fmt, Namespace::ValueNS);
+        cx.print_alloc_ids = true;
+        cx.pretty_print_const(literal, print_types)?;
+        Ok(())
+    })
+}
+
 impl<'tcx> graph::DirectedGraph for Body<'tcx> {
     type Node = BasicBlock;
 }
index 13996a74acb3574306a70e9d59fcc8529e6d96a1..feb663192671254004096cff7d5212f5099d80e8 100644 (file)
@@ -149,7 +149,9 @@ pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx>
     {
         match *self {
             Rvalue::Use(ref operand) => operand.ty(local_decls, tcx),
-            Rvalue::Repeat(ref operand, count) => tcx.mk_array(operand.ty(local_decls, tcx), count),
+            Rvalue::Repeat(ref operand, count) => {
+                tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count))
+            }
             Rvalue::Ref(reg, bk, ref place) => {
                 let place_ty = place.ty(local_decls, tcx).ty;
                 tcx.mk_ref(reg, ty::TypeAndMut { ty: place_ty, mutbl: bk.to_mutbl_lossy() })
index 00310ef9b3127445763df4a832bff718cc6a7c69..5d1f6ae3877402a861c8e53f90eb5084a813b431 100644 (file)
@@ -8,7 +8,7 @@
 use crate::infer::canonical::Canonical;
 use crate::middle::region;
 use crate::mir::interpret::ConstValue;
-use crate::mir::interpret::Scalar;
+use crate::mir::interpret::{LitToConstInput, Scalar};
 use crate::mir::Promoted;
 use crate::ty::layout::VariantIdx;
 use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
@@ -2401,7 +2401,75 @@ pub struct Const<'tcx> {
 #[cfg(target_arch = "x86_64")]
 static_assert_size!(Const<'_>, 48);
 
+/// Returns the `DefId` of the constant parameter that the provided expression is a path to.
+fn const_param_def_id(expr: &hir::Expr<'_>) -> Option<DefId> {
+    // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
+    // currently have to be wrapped in curly brackets, so it's necessary to special-case.
+    let expr = match &expr.kind {
+        hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
+            block.expr.as_ref().unwrap()
+        }
+        _ => expr,
+    };
+
+    match &expr.kind {
+        hir::ExprKind::Path(hir::QPath::Resolved(_, path)) => match path.res {
+            hir::def::Res::Def(hir::def::DefKind::ConstParam, did) => Some(did),
+            _ => None,
+        },
+        _ => None,
+    }
+}
+
 impl<'tcx> Const<'tcx> {
+    pub fn from_hir_anon_const(
+        tcx: TyCtxt<'tcx>,
+        ast_const: &hir::AnonConst,
+        ty: Ty<'tcx>,
+    ) -> &'tcx Self {
+        debug!("Const::from_hir_anon_const(id={:?}, ast_const={:?})", ast_const.hir_id, ast_const);
+
+        let def_id = tcx.hir().local_def_id(ast_const.hir_id);
+
+        let expr = &tcx.hir().body(ast_const.body).value;
+
+        let lit_input = match expr.kind {
+            hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
+            hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => match expr.kind {
+                hir::ExprKind::Lit(ref lit) => {
+                    Some(LitToConstInput { lit: &lit.node, ty, neg: true })
+                }
+                _ => None,
+            },
+            _ => None,
+        };
+
+        if let Some(lit_input) = lit_input {
+            // If an error occurred, ignore that it's a literal and leave reporting the error up to
+            // mir.
+            if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) {
+                return c;
+            } else {
+                tcx.sess.delay_span_bug(expr.span, "ast_const_to_const: couldn't lit_to_const");
+            }
+        }
+
+        let kind = if let Some(def_id) = const_param_def_id(expr) {
+            // Find the name and index of the const parameter by indexing the generics of the
+            // parent item and construct a `ParamConst`.
+            let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
+            let item_id = tcx.hir().get_parent_node(hir_id);
+            let item_def_id = tcx.hir().local_def_id(item_id);
+            let generics = tcx.generics_of(item_def_id);
+            let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)];
+            let name = tcx.hir().name(hir_id);
+            ty::ConstKind::Param(ty::ParamConst::new(index, name))
+        } else {
+            ty::ConstKind::Unevaluated(def_id, InternalSubsts::identity_for_item(tcx, def_id), None)
+        };
+        tcx.mk_const(ty::Const { val: kind, ty })
+    }
+
     #[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 245df0846b583cc8c77ad0140d6b09250a8bbcfb..880bce7fde48787bae133261cedd815c411cfbc0 100644 (file)
@@ -106,6 +106,9 @@ pub fn codegen_rvalue(
                     }
                 }
 
+                let count =
+                    self.monomorphize(&count).eval_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all());
+
                 bx.write_operand_repeatedly(cg_elem, count, dest)
             }
 
index 521861624cb7a8f80ec755eca8cb900ed98f5ef3..e1aacb1fa26371144890261da9f13e29ba20c3a2 100644 (file)
@@ -1986,7 +1986,11 @@ fn check_rvalue(
             }
 
             Rvalue::Repeat(operand, len) => {
-                if *len > 1 {
+                // If the length cannot be evaluated we must assume that the length can be larger
+                // than 1.
+                // If the length is larger than 1, the repeat expression will need to copy the
+                // element, so we require the `Copy` trait.
+                if len.try_eval_usize(tcx, self.param_env).map_or(true, |len| len > 1) {
                     if let Operand::Move(_) = operand {
                         // While this is located in `nll::typeck` this error is not an NLL error, it's
                         // a required check to make sure that repeated elements implement `Copy`.
index 02b596863ab4090b9026b72b4a4967559bbb89b4..b9c9e9834eff8a16ee5c8571729eb8b6f98cd771 100644 (file)
@@ -3,7 +3,7 @@
 use crate::hair::cx::Cx;
 use crate::hair::util::UserAnnotatedTyHelpers;
 use crate::hair::*;
-use rustc::mir::interpret::{ErrorHandled, Scalar};
+use rustc::mir::interpret::Scalar;
 use rustc::mir::BorrowKind;
 use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast};
 use rustc::ty::subst::{InternalSubsts, SubstsRef};
@@ -406,34 +406,7 @@ fn make_mirror_unadjusted<'a, 'tcx>(
 
         // Now comes the rote stuff:
         hir::ExprKind::Repeat(ref v, ref count) => {
-            let def_id = cx.tcx.hir().local_def_id(count.hir_id);
-            let substs = InternalSubsts::identity_for_item(cx.tcx, def_id);
-            let span = cx.tcx.def_span(def_id);
-            let count = match cx.tcx.const_eval_resolve(
-                ty::ParamEnv::reveal_all(),
-                def_id,
-                substs,
-                None,
-                Some(span),
-            ) {
-                Ok(cv) => {
-                    if let Some(count) = cv.try_to_bits_for_ty(
-                        cx.tcx,
-                        ty::ParamEnv::reveal_all(),
-                        cx.tcx.types.usize,
-                    ) {
-                        count as u64
-                    } else {
-                        bug!("repeat count constant value can't be converted to usize");
-                    }
-                }
-                Err(ErrorHandled::Reported) => 0,
-                Err(ErrorHandled::TooGeneric) => {
-                    let span = cx.tcx.def_span(def_id);
-                    cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters");
-                    0
-                }
-            };
+            let count = ty::Const::from_hir_anon_const(cx.tcx, count, cx.tcx.types.usize);
 
             ExprKind::Repeat { value: v.to_ref(), count }
         }
index cb93ba7c9250f3b31c216b6f48f3d71f972aaca5..77042240acf32fde0a82136cdf6c2a2f1c937abb 100644 (file)
     },
     Repeat {
         value: ExprRef<'tcx>,
-        count: u64,
+        count: &'tcx Const<'tcx>,
     },
     Array {
         fields: Vec<ExprRef<'tcx>>,
index 408e5c2d2f24d78462ce1a8048d0f17816c2c346..2d7bf81aedd6d9061c08ab8737c9de717f92bfe7 100644 (file)
@@ -22,7 +22,7 @@
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::print;
-use rustc_hir::{Constness, ExprKind, GenericArg, GenericArgs};
+use rustc_hir::{Constness, GenericArg, GenericArgs};
 use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, LATE_BOUND_LIFETIME_ARGUMENTS};
 use rustc_session::parse::feature_err;
 use rustc_session::Session;
@@ -39,8 +39,6 @@
 use std::iter;
 use std::slice;
 
-use rustc::mir::interpret::LitToConstInput;
-
 #[derive(Debug)]
 pub struct PathSeg(pub DefId, pub usize);
 
@@ -782,7 +780,7 @@ fn create_substs_for_ast_path<'a>(
                     }
                 }
                 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
-                    self.ast_const_to_const(&ct.value, tcx.type_of(param.def_id)).into()
+                    ty::Const::from_hir_anon_const(tcx, &ct.value, tcx.type_of(param.def_id)).into()
                 }
                 _ => unreachable!(),
             },
@@ -2766,7 +2764,7 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
                     .unwrap_or(tcx.types.err)
             }
             hir::TyKind::Array(ref ty, ref length) => {
-                let length = self.ast_const_to_const(length, tcx.types.usize);
+                let length = ty::Const::from_hir_anon_const(tcx, length, tcx.types.usize);
                 let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(&ty), length));
                 self.normalize_ty(ast_ty.span, array_ty)
             }
@@ -2798,75 +2796,6 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
         result_ty
     }
 
-    /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
-    pub fn const_param_def_id(&self, expr: &hir::Expr<'_>) -> Option<DefId> {
-        // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
-        // currently have to be wrapped in curly brackets, so it's necessary to special-case.
-        let expr = match &expr.kind {
-            ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
-                block.expr.as_ref().unwrap()
-            }
-            _ => expr,
-        };
-
-        match &expr.kind {
-            ExprKind::Path(hir::QPath::Resolved(_, path)) => match path.res {
-                Res::Def(DefKind::ConstParam, did) => Some(did),
-                _ => None,
-            },
-            _ => None,
-        }
-    }
-
-    pub fn ast_const_to_const(
-        &self,
-        ast_const: &hir::AnonConst,
-        ty: Ty<'tcx>,
-    ) -> &'tcx ty::Const<'tcx> {
-        debug!("ast_const_to_const(id={:?}, ast_const={:?})", ast_const.hir_id, ast_const);
-
-        let tcx = self.tcx();
-        let def_id = tcx.hir().local_def_id(ast_const.hir_id);
-
-        let expr = &tcx.hir().body(ast_const.body).value;
-
-        let lit_input = match expr.kind {
-            hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
-            hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => match expr.kind {
-                hir::ExprKind::Lit(ref lit) => {
-                    Some(LitToConstInput { lit: &lit.node, ty, neg: true })
-                }
-                _ => None,
-            },
-            _ => None,
-        };
-
-        if let Some(lit_input) = lit_input {
-            // If an error occurred, ignore that it's a literal and leave reporting the error up to
-            // mir.
-            if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) {
-                return c;
-            } else {
-                tcx.sess.delay_span_bug(expr.span, "ast_const_to_const: couldn't lit_to_const");
-            }
-        }
-
-        let kind = if let Some(def_id) = self.const_param_def_id(expr) {
-            // Find the name and index of the const parameter by indexing the generics of the
-            // parent item and construct a `ParamConst`.
-            let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
-            let item_id = tcx.hir().get_parent_node(hir_id);
-            let item_def_id = tcx.hir().local_def_id(item_id);
-            let generics = tcx.generics_of(item_def_id);
-            let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)];
-            let name = tcx.hir().name(hir_id);
-            ty::ConstKind::Param(ty::ParamConst::new(index, name))
-        } else {
-            ty::ConstKind::Unevaluated(def_id, InternalSubsts::identity_for_item(tcx, def_id), None)
-        };
-        tcx.mk_const(ty::Const { val: kind, ty })
-    }
-
     pub fn impl_trait_ty_to_ty(
         &self,
         def_id: DefId,
index 7203980b2388f482467b394208143abf973a4441..e57e6cd80ca14c8ef7f17b6b82dbf7fdce0b4f34 100644 (file)
@@ -18,7 +18,6 @@
 use crate::util::common::ErrorReported;
 
 use rustc::middle::lang_items;
-use rustc::mir::interpret::ErrorHandled;
 use rustc::ty;
 use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::Ty;
@@ -1009,12 +1008,7 @@ fn check_expr_repeat(
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let count_def_id = tcx.hir().local_def_id(count.hir_id);
-        let count = if self.const_param_def_id(count).is_some() {
-            Ok(self.to_const(count, tcx.type_of(count_def_id)))
-        } else {
-            tcx.const_eval_poly(count_def_id)
-                .map(|val| ty::Const::from_value(tcx, val, tcx.type_of(count_def_id)))
-        };
+        let count = self.to_const(count, tcx.type_of(count_def_id));
 
         let uty = match expected {
             ExpectHasType(uty) => match uty.kind {
@@ -1042,17 +1036,8 @@ fn check_expr_repeat(
         if element_ty.references_error() {
             return tcx.types.err;
         }
-        match count {
-            Ok(count) => tcx.mk_ty(ty::Array(t, count)),
-            Err(ErrorHandled::TooGeneric) => {
-                self.tcx.sess.span_err(
-                    tcx.def_span(count_def_id),
-                    "array lengths can't depend on generic parameters",
-                );
-                tcx.types.err
-            }
-            Err(ErrorHandled::Reported) => tcx.types.err,
-        }
+
+        tcx.mk_ty(ty::Array(t, count))
     }
 
     fn check_expr_tuple(
index 32f0f578d057f3a25a0bccc2411a34c15d300ed7..292ad1e94a72eea68b77819f279ec0222e95877d 100644 (file)
@@ -3279,13 +3279,8 @@ pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
         ty
     }
 
-    /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
-    pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
-        AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
-    }
-
     pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
-        AstConv::ast_const_to_const(self, ast_c, ty)
+        ty::Const::from_hir_anon_const(self.tcx, ast_c, ty)
     }
 
     // If the type given by the user has free regions, save it for later, since
index 597fbbf00d53cf8c36fea2a2afa87745b4f83c42..3a022230b39a782c3eff49a0844b8b47324ce2f5 100644 (file)
@@ -7,10 +7,5 @@ fn main() {
     //~^ ERROR `while` is not allowed in a `const`
     //~| WARN denote infinite loops with
     [(); { for _ in 0usize.. {}; 0}];
-    //~^ ERROR calls in constants are limited to constant functions
-    //~| ERROR calls in constants are limited to constant functions
-    //~| ERROR `for` is not allowed in a `const`
-    //~| ERROR references in constants may only refer to immutable values
-    //~| ERROR evaluation of constant value failed
-    //~| ERROR constant contains unimplemented expression type
+    //~^ ERROR `for` is not allowed in a `const`
 }
index 1e649a556e01de0f3177be8a305a82dd92c77e24..634638e1335b327576797cf90a7a99f672d203f6 100644 (file)
@@ -3,4 +3,5 @@ fn main() {
     //~^ ERROR: invalid label name `'static`
     //~| ERROR: `loop` is not allowed in a `const`
     //~| ERROR: type annotations needed
+    //~| ERROR mismatched types
 }
index b9225e55fe5c7c31ebf7fa8ef6e0edbf7cdb153d..acb59c7b02d1b584c0da3fa2acfed9e95913c3ea 100644 (file)
@@ -19,7 +19,15 @@ error[E0282]: type annotations needed
 LL |     [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
    |                              ^ consider giving this closure parameter a type
 
-error: aborting due to 3 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-52437.rs:2:5
+   |
+LL | fn main() {
+   |           - expected `()` because of default return type
+LL |     [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[(); _]`
+
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0282, E0658.
+Some errors have detailed explanations: E0282, E0308, E0658.
 For more information about an error, try `rustc --explain E0282`.
index 5b5e431bf2ff6d6824e010b8469010d88f753cad..165d3e1c2e60169af4f1b669ae0c63a6646005f4 100644 (file)
@@ -1,9 +1,10 @@
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
+// build-pass
+
 fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
     [x; N]
-    //~^ ERROR array lengths can't depend on generic parameters
 }
 
 fn main() {
index 949fa896d8780bfee6151da612a488bed1f0e51b..d48d8ff689462b330d554f55734754998b1b903d 100644 (file)
@@ -6,11 +6,3 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-error: array lengths can't depend on generic parameters
-  --> $DIR/issue-61336-1.rs:5:9
-   |
-LL |     [x; N]
-   |         ^
-
-error: aborting due to previous error
-
index 7bb36f41b8f9d1a3cd0b76a3ed31fa99b79dd35e..c5bf6b6ce94a8a4ae4ab532663bb070c94bf494e 100644 (file)
@@ -2,13 +2,12 @@
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
 fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
-    [x; {N}]
-    //~^ ERROR array lengths can't depend on generic parameters
+    [x; { N }]
 }
 
 fn g<T, const N: usize>(x: T) -> [T; N] {
-    [x; {N}]
-    //~^ ERROR array lengths can't depend on generic parameters
+    [x; { N }]
+    //~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied
 }
 
 fn main() {
index 63f86c81b1e7f0a727778c44e2afef0c33e3abb4..9ced427b93c6589046893e785b9887ef8639d2ca 100644 (file)
@@ -6,17 +6,19 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-error: array lengths can't depend on generic parameters
-  --> $DIR/issue-61336-2.rs:5:9
+error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
+  --> $DIR/issue-61336-2.rs:9:5
    |
-LL |     [x; {N}]
-   |         ^^^
-
-error: array lengths can't depend on generic parameters
-  --> $DIR/issue-61336-2.rs:10:9
+LL |     [x; { N }]
+   |     ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
+   |
+help: consider restricting this type parameter with `T: std::marker::Copy`
+  --> $DIR/issue-61336-2.rs:8:6
    |
-LL |     [x; {N}]
-   |         ^^^
+LL | fn g<T, const N: usize>(x: T) -> [T; N] {
+   |      ^
+   = note: the `Copy` trait is required because the repeated element will be copied
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0277`.
index edc012cbb3d13c7f30ee803381d5b4c94130a5bd..7e84e62d8be421f9e33f44b4b8a7af1407a616b4 100644 (file)
@@ -3,12 +3,11 @@
 
 fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
     [x; N]
-    //~^ ERROR array lengths can't depend on generic parameters
 }
 
 fn g<T, const N: usize>(x: T) -> [T; N] {
     [x; N]
-    //~^ ERROR array lengths can't depend on generic parameters
+    //~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied
 }
 
 fn main() {
index f96e8e02d4ec03ca347561411e397ed1b8cb0c8f..ace7955fbdd77ffd1b0d9f24940a65e767152e9f 100644 (file)
@@ -6,17 +6,19 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-error: array lengths can't depend on generic parameters
-  --> $DIR/issue-61336.rs:5:9
+error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
+  --> $DIR/issue-61336.rs:9:5
    |
 LL |     [x; N]
-   |         ^
-
-error: array lengths can't depend on generic parameters
-  --> $DIR/issue-61336.rs:10:9
+   |     ^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
-LL |     [x; N]
-   |         ^
+help: consider restricting this type parameter with `T: std::marker::Copy`
+  --> $DIR/issue-61336.rs:8:6
+   |
+LL | fn g<T, const N: usize>(x: T) -> [T; N] {
+   |      ^
+   = note: the `Copy` trait is required because the repeated element will be copied
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0277`.
index c5e6fe9104bc979ab5342426b2110f1a2884ed59..14b1190df0f995caf09f4d72513d15ef56484d93 100644 (file)
@@ -1,9 +1,10 @@
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
+// build-pass
+
 fn foo<const N: usize>() {
     let _ = [0u64; N + 1];
-    //~^ ERROR array lengths can't depend on generic parameters
 }
 
 fn main() {}
index 9cdccf8407c9bf6fae0bb6ffc53ac1d4cc3e6f14..47dd3c01fa9e003f57c36b1e4c9d132fe75aaf59 100644 (file)
@@ -6,11 +6,3 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-error: array lengths can't depend on generic parameters
-  --> $DIR/issue-62456.rs:5:20
-   |
-LL |     let _ = [0u64; N + 1];
-   |                    ^^^^^
-
-error: aborting due to previous error
-
index 74ed3d354fc747562ff3d2b87a0cd1003bac99b3..cd3cfaac3b95b81f8ad2fdb22f160718dc26574b 100644 (file)
@@ -16,7 +16,7 @@ impl<const X: usize> HasSize for ArrayHolder<{ X }> {
 impl<const X: usize> ArrayHolder<{ X }> {
     pub const fn new() -> Self {
         ArrayHolder([0; Self::SIZE])
-        //~^ ERROR: array lengths can't depend on generic parameters
+        //~^ ERROR: mismatched types
     }
 }
 
index c2a752ec1715fc2f6d8b6c77258d9af1d6e59e83..4482389bbdd4954c88abca5ff4774f3050247f88 100644 (file)
@@ -1,8 +1,12 @@
-error: array lengths can't depend on generic parameters
-  --> $DIR/issue-62504.rs:18:25
+error[E0308]: mismatched types
+  --> $DIR/issue-62504.rs:18:21
    |
 LL |         ArrayHolder([0; Self::SIZE])
-   |                         ^^^^^^^^^^
+   |                     ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
+   |
+   = note: expected array `[u32; _]`
+              found array `[u32; _]`
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0308`.
index 79c5ac9dd187e035f8be0b93c60a6eb025e7bf3e..3d657b0947b18f28a0eab91ec3d6f3bdefbd48ba 100644 (file)
@@ -1,5 +1,7 @@
 // Regression test for #67739
 
+// check-pass
+
 #![allow(incomplete_features)]
 #![feature(const_generics)]
 
@@ -10,7 +12,6 @@ pub trait Trait {
 
     fn associated_size(&self) -> usize {
         [0u8; mem::size_of::<Self::Associated>()];
-        //~^ ERROR: array lengths can't depend on generic parameters
         0
     }
 }
diff --git a/src/test/ui/const-generics/issues/issue-67739.stderr b/src/test/ui/const-generics/issues/issue-67739.stderr
deleted file mode 100644 (file)
index a31b556..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-error: array lengths can't depend on generic parameters
-  --> $DIR/issue-67739.rs:12:15
-   |
-LL |         [0u8; mem::size_of::<Self::Associated>()];
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
index 6fd8e9cbc806b17c872bcc12c77623134faa428a..3ae55ebdbaf357c211dcced4d6658820afef99da 100644 (file)
@@ -19,6 +19,7 @@
     : [u32; (i8::MAX as usize) + 1]
     = [0; (i8::MAX + 1) as usize];
 //~^ ERROR evaluation of constant value failed
+//~| ERROR mismatched types
 
 fn main() {
     foo(&A_I8_I[..]);
index 2c5b4607aa4d3ca802d13aa78f3f1b69437f46d4..94b7c12fc1a8b138763a7d8602fe91eea7d2875b 100644 (file)
@@ -4,6 +4,16 @@ error[E0080]: evaluation of constant value failed
 LL |     = [0; (i8::MAX + 1) as usize];
    |           ^^^^^^^^^^^^^ attempt to add with overflow
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/const-eval-overflow-3.rs:20:7
+   |
+LL |     = [0; (i8::MAX + 1) as usize];
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `128usize`, found `(i8::MAX + 1) as usize`
+   |
+   = note: expected array `[u32; 128]`
+              found array `[u32; _]`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0080`.
+Some errors have detailed explanations: E0080, E0308.
+For more information about an error, try `rustc --explain E0080`.
index db6f17a671aea5b71db75f41abe6837018d67ef4..e7b88e00febaa3a94230171974667ee02d6c2e5e 100644 (file)
@@ -18,6 +18,7 @@
     = [0; (i8::MAX + 1u8) as usize];
 //~^ ERROR mismatched types
 //~| ERROR cannot add `u8` to `i8`
+//~| ERROR mismatched types
 
 fn main() {
     foo(&A_I8_I[..]);
index 3da34fe9af7ecbe8ba069bd644be8d4a769630b5..aebe4feef8d5f7931ff932b18c879d635e50bd2d 100644 (file)
@@ -12,7 +12,16 @@ LL |     = [0; (i8::MAX + 1u8) as usize];
    |
    = help: the trait `std::ops::Add<u8>` is not implemented for `i8`
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/const-eval-overflow-3b.rs:18:7
+   |
+LL |     = [0; (i8::MAX + 1u8) as usize];
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `128usize`, found `(i8::MAX + 1u8) as usize`
+   |
+   = note: expected array `[u32; 128]`
+              found array `[u32; _]`
+
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
index d820c7051612456a128f108dfcdc0aeaa26b00eb..df4cc8e3026778177bb0098fdad8c05a4d9a4098 100644 (file)
@@ -1,6 +1,4 @@
 fn main() {
     [();  { &loop { break } as *const _ as usize } ];
-    //~^ ERROR casting pointers to integers in constants is unstable
-    //~| ERROR `loop` is not allowed in a `const`
-    //~| ERROR evaluation of constant value failed
+    //~^ ERROR `loop` is not allowed in a `const`
 }
index eda2dbf0b6b1569ff8f412bf2436b78b325f2106..0ea974f1f66662e85aaafbbf8347ae493cced1fb 100644 (file)
@@ -7,22 +7,6 @@ LL |     [();  { &loop { break } as *const _ as usize } ];
    = note: see issue #52000 <https://github.com/rust-lang/rust/issues/52000> for more information
    = help: add `#![feature(const_loop)]` to the crate attributes to enable
 
-error[E0658]: casting pointers to integers in constants is unstable
-  --> $DIR/issue-52442.rs:2:13
-   |
-LL |     [();  { &loop { break } as *const _ as usize } ];
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
-   = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
-
-error[E0080]: evaluation of constant value failed
-  --> $DIR/issue-52442.rs:2:13
-   |
-LL |     [();  { &loop { break } as *const _ as usize } ];
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0080, E0658.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0658`.
index 80494d1662987e98efbf5bf12896aeafe35a5887..5cfe36f57e6478e915b75934496aca77ab257d26 100644 (file)
@@ -2,7 +2,7 @@ fn main() {
     // Make sure match uses the usual pointer comparison code path -- i.e., it should complain
     // that pointer comparison is disallowed, not that parts of a pointer are accessed as raw
     // bytes.
-    let _: [u8; 0] = [4; {
+    let _: [u8; 0] = [4; { //~ ERROR mismatched types
         match &1 as *const i32 as usize {
             //~^ ERROR casting pointers to integers in constants
             //~| ERROR `match` is not allowed in a `const`
index b47f6d5f845feeab0e81fbd237a557ebbfbf939f..7c4da5e7d86cab11cf94175b6a0d0c1d2b00bab9 100644 (file)
@@ -28,7 +28,30 @@ error[E0080]: evaluation of constant value failed
 LL |         match &1 as *const i32 as usize {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants
 
-error: aborting due to 3 previous errors
+error[E0308]: mismatched types
+  --> $DIR/match-test-ptr-null.rs:5:22
+   |
+LL |       let _: [u8; 0] = [4; {
+   |  ____________-------___^
+   | |            |
+   | |            expected due to this
+LL | |         match &1 as *const i32 as usize {
+LL | |
+LL | |
+...  |
+LL | |         }
+LL | |     }];
+   | |______^ expected `0usize`, found `{
+        match &1 as *const i32 as usize {
+            0 => 42,
+            n => n,
+        }
+    }`
+   |
+   = note: expected array `[u8; 0]`
+              found array `[u8; _]`
+
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0080, E0658.
+Some errors have detailed explanations: E0080, E0308, E0658.
 For more information about an error, try `rustc --explain E0080`.
index 2d4c939f47d795369a55f4c89dc68bc0d1263e77..ded79458e637f12167d27608a15c1ea7e83d5ce0 100644 (file)
@@ -6,5 +6,4 @@ fn main() {
     //~| ERROR: type annotations needed
     [(); &(static || {}) as *const _ as usize];
     //~^ ERROR: closures cannot be static
-    //~| ERROR: evaluation of constant value failed
 }
index e9539d24118a0533bbc18e447589c3693d2fd9ad..d25c11138f4003288adef7229b8792047d968f3e 100644 (file)
@@ -16,13 +16,7 @@ error[E0282]: type annotations needed
 LL |     [(); &(static |x| {}) as *const _ as usize];
    |                    ^ consider giving this closure parameter a type
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/issue-52432.rs:7:10
-   |
-LL |     [(); &(static || {}) as *const _ as usize];
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0080, E0282, E0697.
-For more information about an error, try `rustc --explain E0080`.
+Some errors have detailed explanations: E0282, E0697.
+For more information about an error, try `rustc --explain E0282`.
index 7a299169bc4e19e59a5c0d63749140049a14fe9a..7e4d4dbe44610a7f0a9d45d428f9cf1e850cac34 100644 (file)
@@ -7,6 +7,7 @@ pub fn crash() -> bool {
         [5; Self::HOST_SIZE] == [6; 0] //~ ERROR no associated item named `HOST_SIZE`
         //~^ the size for values of type `A` cannot be known
         //~| the size for values of type `B` cannot be known
+        //~| binary operation `==` cannot be applied to type `[{integer}; _]`
     }
 }
 
index 8836de0023c9d5370527f918b42cebcb27bc7d35..ffa28225b79c65ca7250af558a61e8ae118fcfd2 100644 (file)
@@ -41,7 +41,15 @@ LL |         [5; Self::HOST_SIZE] == [6; 0]
    = help: the trait `std::marker::Sized` is not implemented for `B`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
 
-error: aborting due to 3 previous errors
+error[E0369]: binary operation `==` cannot be applied to type `[{integer}; _]`
+  --> $DIR/too_generic_eval_ice.rs:7:30
+   |
+LL |         [5; Self::HOST_SIZE] == [6; 0]
+   |         -------------------- ^^ ------ [{integer}; 0]
+   |         |
+   |         [{integer}; _]
+
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0277, E0599.
+Some errors have detailed explanations: E0277, E0369, E0599.
 For more information about an error, try `rustc --explain E0277`.
index 3a52e4d6216a5e30b944953c1210c8b410265212..ec0275b2d6c1274f89d2506e8f264888af1ac3e5 100644 (file)
@@ -17,4 +17,5 @@ fn main() {
         = [0; Dim3::dim()];
         //~^ ERROR E0015
         //~| ERROR E0080
+        //~| ERROR mismatched types
 }
index 586debbbe535348fc2bcd9e9566194be05df8ed7..7cbf63c2da0a96336162f1ea61b1e54f624f34fa 100644 (file)
@@ -22,7 +22,19 @@ error[E0080]: evaluation of constant value failed
 LL |         = [0; Dim3::dim()];
    |               ^^^^^^^^^^^ calling non-const function `<Dim3 as Dim>::dim`
 
-error: aborting due to 4 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-39559-2.rs:17:11
+   |
+LL |     let array: [usize; Dim3::dim()]
+   |                -------------------- expected due to this
+...
+LL |         = [0; Dim3::dim()];
+   |           ^^^^^^^^^^^^^^^^ expected `Dim3::dim()`, found `Dim3::dim()`
+   |
+   = note: expected array `[usize; _]`
+              found array `[usize; _]`
+
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0015, E0080.
+Some errors have detailed explanations: E0015, E0080, E0308.
 For more information about an error, try `rustc --explain E0015`.
index fed08902c8b9d35def06f90722a25d06b55a4bdc..2688049fcc9ffa357d5c23a1efddc87e2668f600 100644 (file)
@@ -4,5 +4,6 @@
 static B: [u32; 1] = [0; A.len()];
 //~^ ERROR [E0013]
 //~| ERROR evaluation of constant value failed
+//~| ERROR mismatched types
 
 fn main() {}
index 502825e9766e3d90af04bd09c311cdfccecbdc26..e076e183937f2539b016b1142151057094b38462 100644 (file)
@@ -12,7 +12,16 @@ error[E0080]: evaluation of constant value failed
 LL | static B: [u32; 1] = [0; A.len()];
    |                          ^ constant accesses static
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-52060.rs:4:22
+   |
+LL | static B: [u32; 1] = [0; A.len()];
+   |                      ^^^^^^^^^^^^ expected `1usize`, found `A.len()`
+   |
+   = note: expected array `[u32; 1]`
+              found array `[u32; _]`
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0013, E0080.
+Some errors have detailed explanations: E0013, E0080, E0308.
 For more information about an error, try `rustc --explain E0013`.
index d060f26fb2a08aaa971ad3005ba767878a2b6871..2c5257ce063cb525897cd2c19a1b4380f1d0c37d 100644 (file)
@@ -19,5 +19,4 @@ impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA`
 
 fn main() {
     let _ = [0; B::VALUE];
-    //~^ ERROR array lengths can't depend on generic parameters
 }
index c6b2b4d27a208f72d3c8fc33d1fbfa18ead7386c..8ae0f8b804c93e822b6b5f97fa81105cb3215dcc 100644 (file)
@@ -13,13 +13,7 @@ LL |     type MyA: TraitA;
 LL | impl TraitB for B {
    | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation
 
-error: array lengths can't depend on generic parameters
-  --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17
-   |
-LL |     let _ = [0; B::VALUE];
-   |                 ^^^^^^^^
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0046, E0437.
 For more information about an error, try `rustc --explain E0046`.
index efad00b272cdc9201bad26907e4f7815773d2c65..4a2d1d9f921cb97985e5d5c348bff30253696799 100644 (file)
@@ -28,6 +28,12 @@ error[E0308]: mismatched types
 LL |     let e = [0; "foo"];
    |                 ^^^^^ expected `usize`, found `&str`
 
+error[E0308]: mismatched types
+  --> $DIR/repeat_count.rs:28:17
+   |
+LL |     let g = [0; G { g: () }];
+   |                 ^^^^^^^^^^^ expected `usize`, found struct `main::G`
+
 error[E0308]: mismatched types
   --> $DIR/repeat_count.rs:19:17
    |
@@ -50,12 +56,6 @@ help: you can convert an `isize` to `usize` and panic if the converted value wou
 LL |     let f = [0_usize; (-1_isize).try_into().unwrap()];
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0308]: mismatched types
-  --> $DIR/repeat_count.rs:28:17
-   |
-LL |     let g = [0; G { g: () }];
-   |                 ^^^^^^^^^^^ expected `usize`, found struct `main::G`
-
 error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0308, E0435.
index 63d3431ec9b2f7bb9a62163667bca421bdf8264d..708d72a2df756e1681429cf66c23d2cae9315de1 100644 (file)
@@ -24,6 +24,7 @@ fn i<const N: usize>() {
     static a: [u8; N] = [0; N];
     //~^ ERROR can't use generic parameters from outer function
     //~^^ ERROR can't use generic parameters from outer function
+    //~| ERROR mismatched types
 }
 
 fn main() {}
index 82e2aa2db8e25efa6ce3338a2f38c36e91f09211..97c60c72298372cc250e4fa0721c84a7f6e496cd 100644 (file)
@@ -48,6 +48,16 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-error: aborting due to 5 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-65035-static-with-parent-generics.rs:24:25
+   |
+LL |     static a: [u8; N] = [0; N];
+   |                         ^^^^^^ expected `N`, found `N`
+   |
+   = note: expected array `[u8; _]`
+              found array `[u8; _]`
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0401`.
+Some errors have detailed explanations: E0308, E0401.
+For more information about an error, try `rustc --explain E0308`.