Evaluate repeat expression lengths as late as possible
This commit is contained in:
parent
8ff785011b
commit
799b15ed96
src
librustc
librustc_codegen_ssa/mir
librustc_mir/borrow_check/type_check
librustc_mir_build/hair
librustc_typeck
test
compile-fail
ui
closures
const-generics/issues
issue-61336-1.rsissue-61336-1.stderrissue-61336-2.rsissue-61336-2.stderrissue-61336.rsissue-61336.stderrissue-62456.rsissue-62456.stderrissue-62504.rsissue-62504.stderrissue-67739.rsissue-67739.stderr
consts
const-eval
const-eval-overflow-3.rsconst-eval-overflow-3.stderrconst-eval-overflow-3b.rsconst-eval-overflow-3b.stderrissue-52442.rsissue-52442.stderrmatch-test-ptr-null.rsmatch-test-ptr-null.stderr
issue-52432.rsissue-52432.stderrtoo_generic_eval_ice.rstoo_generic_eval_ice.stderrissues
issue-39559-2.rsissue-39559-2.stderrissue-52060.rsissue-52060.stderrissue-69602-type-err-during-codegen-ice.rsissue-69602-type-err-during-codegen-ice.stderr
repeat_count.stderrresolve
@ -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 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
||||
|
||||
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 @@ impl<'tcx> Debug for Constant<'tcx> {
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -149,7 +149,9 @@ impl<'tcx> Rvalue<'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() })
|
||||
|
@ -8,7 +8,7 @@ use self::TyKind::*;
|
||||
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 })
|
||||
|
@ -106,6 +106,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
}
|
||||
|
||||
let count =
|
||||
self.monomorphize(&count).eval_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all());
|
||||
|
||||
bx.write_operand_repeatedly(cg_elem, count, dest)
|
||||
}
|
||||
|
||||
|
@ -1986,7 +1986,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
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`.
|
||||
|
@ -3,7 +3,7 @@ use crate::hair::cx::to_ref::ToRef;
|
||||
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 }
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ crate enum ExprKind<'tcx> {
|
||||
},
|
||||
Repeat {
|
||||
value: ExprRef<'tcx>,
|
||||
count: u64,
|
||||
count: &'tcx Const<'tcx>,
|
||||
},
|
||||
Array {
|
||||
fields: Vec<ExprRef<'tcx>>,
|
||||
|
@ -22,7 +22,7 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
|
||||
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::collections::BTreeSet;
|
||||
use std::iter;
|
||||
use std::slice;
|
||||
|
||||
use rustc::mir::interpret::LitToConstInput;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PathSeg(pub DefId, pub usize);
|
||||
|
||||
@ -782,7 +780,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
}
|
||||
(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 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
.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 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
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,
|
||||
|
@ -18,7 +18,6 @@ use crate::type_error_struct;
|
||||
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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
) -> 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
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(
|
||||
|
@ -3279,13 +3279,8 @@ impl<'a, 'tcx> FnCtxt<'a, '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
|
||||
|
@ -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`
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 `[(); _]`
|
||||
|
||||
Some errors have detailed explanations: E0282, E0658.
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0308, E0658.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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`
|
||||
|
|
||||
LL | [x; {N}]
|
||||
| ^^^
|
||||
help: consider restricting this type parameter with `T: std::marker::Copy`
|
||||
--> $DIR/issue-61336-2.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`.
|
||||
|
@ -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() {
|
||||
|
@ -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`.
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -16,7 +16,7 @@ struct ArrayHolder<const X: usize>([u32; 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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -19,6 +19,7 @@ const A_I8_I
|
||||
: [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[..]);
|
||||
|
@ -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; _]`
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0080, E0308.
|
||||
For more information about an error, try `rustc --explain E0080`.
|
||||
|
@ -18,6 +18,7 @@ const A_I8_I
|
||||
= [0; (i8::MAX + 1u8) as usize];
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR cannot add `u8` to `i8`
|
||||
//~| ERROR mismatched types
|
||||
|
||||
fn main() {
|
||||
foo(&A_I8_I[..]);
|
||||
|
@ -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`.
|
||||
|
@ -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`
|
||||
}
|
||||
|
@ -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: aborting due to previous error
|
||||
|
||||
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
|
||||
|
||||
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`.
|
||||
|
@ -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`
|
||||
|
@ -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; _]`
|
||||
|
||||
Some errors have detailed explanations: E0080, E0658.
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0080, E0308, E0658.
|
||||
For more information about an error, try `rustc --explain E0080`.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 3 previous errors
|
||||
|
||||
error: aborting due to 4 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`.
|
||||
|
@ -7,6 +7,7 @@ impl<A, B> Foo<A, B> {
|
||||
[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}; _]`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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}; _]
|
||||
|
||||
Some errors have detailed explanations: E0277, E0599.
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0369, E0599.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -17,4 +17,5 @@ fn main() {
|
||||
= [0; Dim3::dim()];
|
||||
//~^ ERROR E0015
|
||||
//~| ERROR E0080
|
||||
//~| ERROR mismatched types
|
||||
}
|
||||
|
@ -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; _]`
|
||||
|
||||
Some errors have detailed explanations: E0015, E0080.
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0080, E0308.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -4,5 +4,6 @@ static A: &'static [u32] = &[1];
|
||||
static B: [u32; 1] = [0; A.len()];
|
||||
//~^ ERROR [E0013]
|
||||
//~| ERROR evaluation of constant value failed
|
||||
//~| ERROR mismatched types
|
||||
|
||||
fn main() {}
|
||||
|
@ -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; _]`
|
||||
|
||||
Some errors have detailed explanations: E0013, E0080.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0013, E0080, E0308.
|
||||
For more information about an error, try `rustc --explain E0013`.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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`.
|
||||
|
@ -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.
|
||||
|
@ -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() {}
|
||||
|
@ -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; _]`
|
||||
|
||||
For more information about this error, try `rustc --explain E0401`.
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0401.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
Loading…
Reference in New Issue
Block a user