diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 43b429f6947ec..b8910cd6c57bb 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1162,7 +1162,7 @@ impl Expr { /// `min_const_generics` as more complex expressions are not supported. /// /// Does not ensure that the path resolves to a const param, the caller should check this. - pub fn is_potential_trivial_const_arg(&self) -> bool { + pub fn is_potential_trivial_const_arg(&self) -> Option<(NodeId, &Path)> { let this = if let ExprKind::Block(block, None) = &self.kind && block.stmts.len() == 1 && let StmtKind::Expr(expr) = &block.stmts[0].kind @@ -1175,9 +1175,9 @@ impl Expr { if let ExprKind::Path(None, path) = &this.kind && path.is_potential_trivial_const_arg() { - true + Some((this.id, path)) } else { - false + None } } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 5e0ab80c6ac9f..9da1b927af195 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -77,7 +77,10 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::Repeat(expr, count) => { let expr = self.lower_expr(expr); - let count = self.lower_array_length(count); + let count = self.lower_array_length( + count, + &ImplTraitContext::Disallowed(ImplTraitPosition::RepeatExprs), + ); hir::ExprKind::Repeat(expr, count) } ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 2e66c81eb0d05..0d0fb29dcf608 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -168,7 +168,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { intravisit::walk_generic_param(self, param); } - fn visit_const_param_default(&mut self, param: HirId, ct: &'hir AnonConst) { + fn visit_const_param_default(&mut self, param: HirId, ct: &'hir ConstArg<'hir>) { self.with_parent(param, |this| { intravisit::walk_const_param_default(this, ct); }) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1fd7cc6647037..6fa3082a84246 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -257,6 +257,7 @@ enum ImplTraitContext { /// Position in which `impl Trait` is disallowed. #[derive(Debug, Copy, Clone, PartialEq, Eq)] enum ImplTraitPosition { + RepeatExprs, Path, Variable, Trait, @@ -288,6 +289,7 @@ enum ImplTraitPosition { impl std::fmt::Display for ImplTraitPosition { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let name = match self { + ImplTraitPosition::RepeatExprs => "repeat expr lengths", ImplTraitPosition::Path => "paths", ImplTraitPosition::Variable => "variable bindings", ImplTraitPosition::Trait => "traits", @@ -1204,34 +1206,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ty, ); - // Construct an AnonConst where the expr is the "ty"'s path. - - let parent_def_id = self.current_hir_id_owner; - let node_id = self.next_node_id(); - let span = self.lower_span(ty.span); - - // Add a definition for the in-band const def. - let def_id = self.create_def( - parent_def_id.def_id, - node_id, - DefPathData::AnonConst, - span, + return GenericArg::Const( + self.lower_const_arg_param(ty.id, path, itctx), ); - - let path_expr = Expr { - id: ty.id, - kind: ExprKind::Path(None, path.clone()), - span, - attrs: AttrVec::new(), - tokens: None, - }; - - let ct = self.with_new_scopes(|this| hir::AnonConst { - def_id, - hir_id: this.lower_node_id(node_id), - body: this.lower_const_body(path_expr.span, Some(&path_expr)), - }); - return GenericArg::Const(ConstArg { value: ct, span }); } } } @@ -1239,13 +1216,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } GenericArg::Type(self.lower_ty(&ty, itctx)) } - ast::GenericArg::Const(ct) => GenericArg::Const(ConstArg { - value: self.lower_anon_const(&ct), - span: self.lower_span(ct.value.span), + ast::GenericArg::Const(ct) => GenericArg::Const(self.lower_const_arg(ct, itctx)), + } + } + + #[instrument(level = "debug", skip(self), ret)] + fn lower_const_arg( + &mut self, + c: &AnonConst, + itctx: &ImplTraitContext, + ) -> &'hir hir::ConstArg<'hir> { + match c.value.is_potential_trivial_const_arg() { + Some((path_id, param_path)) => self.lower_const_arg_param(path_id, param_path, itctx), + None => self.arena.alloc(ConstArg { + kind: hir::ConstArgKind::AnonConst( + self.lower_span(c.value.span), + self.lower_anon_const(c), + ), }), } } + fn lower_const_arg_param( + &mut self, + path_id: NodeId, + param_path: &Path, + itctx: &ImplTraitContext, + ) -> &'hir hir::ConstArg<'hir> { + self.arena.alloc(ConstArg { + kind: hir::ConstArgKind::Param( + self.lower_node_id(path_id), + self.lower_qpath(path_id, &None, param_path, ParamMode::ExplicitNamed, itctx), + ), + }) + } + #[instrument(level = "debug", skip(self))] fn lower_ty(&mut self, t: &Ty, itctx: &ImplTraitContext) -> &'hir hir::Ty<'hir> { self.arena.alloc(self.lower_ty_direct(t, itctx)) @@ -1360,7 +1365,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { )) } TyKind::Array(ty, length) => { - hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length)) + hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length, itctx)) } TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)), TyKind::TraitObject(bounds, kind) => { @@ -2282,7 +2287,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &ty, &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), ); - let default = default.as_ref().map(|def| self.lower_anon_const(def)); + let default = default.as_ref().map(|def| { + self.lower_const_arg( + def, + &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault), + ) + }); ( hir::ParamName::Plain(self.lower_ident(param.ident)), hir::GenericParamKind::Const { ty, default }, @@ -2389,11 +2399,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.expr_block(block) } - fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen { - match c.value.kind { + fn lower_array_length( + &mut self, + c: &AnonConst, + itctx: &ImplTraitContext, + ) -> &'hir hir::ConstArg<'hir> { + let const_arg = match c.value.kind { ExprKind::Underscore => { if self.tcx.features().generic_arg_infer { - hir::ArrayLen::Infer(self.lower_node_id(c.id), c.value.span) + hir::ConstArg { + kind: hir::ConstArgKind::Infer(self.lower_node_id(c.id), c.value.span), + } } else { feature_err( &self.tcx.sess.parse_sess, @@ -2402,11 +2418,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { "using `_` for array lengths is unstable", ) .stash(c.value.span, StashKey::UnderscoreForArrayLengths); - hir::ArrayLen::Body(self.lower_anon_const(c)) + hir::ConstArg { + kind: hir::ConstArgKind::AnonConst(c.value.span, self.lower_anon_const(c)), + } } } - _ => hir::ArrayLen::Body(self.lower_anon_const(c)), - } + _ => return self.lower_const_arg(c, itctx), + }; + self.arena.alloc(const_arg) } fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst { diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 046d2052968a3..10e1e694b0d97 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -3,7 +3,7 @@ use std::borrow::Cow; use either::{Left, Right}; -use rustc_hir::def::DefKind; +use rustc_hir::def::{CtorKind, DefKind}; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::pretty::display_allocation; @@ -44,6 +44,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( | DefKind::AnonConst | DefKind::InlineConst | DefKind::AssocConst + | DefKind::Ctor(_, CtorKind::Const) ), "Unexpected DefKind: {:?}", ecx.tcx.def_kind(cid.instance.def_id()) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 38cd5865cc326..212bdf0af9b97 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -242,9 +242,33 @@ impl<'hir> PathSegment<'hir> { } #[derive(Clone, Copy, Debug, HashStable_Generic)] -pub struct ConstArg { - pub value: AnonConst, - pub span: Span, +pub struct ConstArg<'hir> { + pub kind: ConstArgKind<'hir>, +} + +#[derive(Clone, Copy, Debug, HashStable_Generic)] +pub enum ConstArgKind<'hir> { + AnonConst(Span, AnonConst), + Param(HirId, QPath<'hir>), + Infer(HirId, Span), +} + +impl<'hir> ConstArg<'hir> { + pub fn span(&self) -> Span { + match self.kind { + ConstArgKind::AnonConst(span, _) => span, + ConstArgKind::Param(_, qpath) => qpath.span(), + ConstArgKind::Infer(_, span) => span, + } + } + + pub fn hir_id(&self) -> HirId { + match self.kind { + ConstArgKind::AnonConst(_, ct) => ct.hir_id, + ConstArgKind::Param(id, _) => id, + ConstArgKind::Infer(id, _) => id, + } + } } #[derive(Clone, Copy, Debug, HashStable_Generic)] @@ -263,7 +287,7 @@ impl InferArg { pub enum GenericArg<'hir> { Lifetime(&'hir Lifetime), Type(&'hir Ty<'hir>), - Const(ConstArg), + Const(&'hir ConstArg<'hir>), Infer(InferArg), } @@ -272,7 +296,7 @@ impl GenericArg<'_> { match self { GenericArg::Lifetime(l) => l.ident.span, GenericArg::Type(t) => t.span, - GenericArg::Const(c) => c.span, + GenericArg::Const(c) => c.span(), GenericArg::Infer(i) => i.span, } } @@ -281,7 +305,7 @@ impl GenericArg<'_> { match self { GenericArg::Lifetime(l) => l.hir_id, GenericArg::Type(t) => t.hir_id, - GenericArg::Const(c) => c.value.hir_id, + GenericArg::Const(c) => c.hir_id(), GenericArg::Infer(i) => i.hir_id, } } @@ -498,7 +522,7 @@ pub enum GenericParamKind<'hir> { Const { ty: &'hir Ty<'hir>, /// Optional default value for the const generic param - default: Option, + default: Option<&'hir ConstArg<'hir>>, }, } @@ -1646,20 +1670,6 @@ impl fmt::Display for ConstContext { /// A literal. pub type Lit = Spanned; -#[derive(Copy, Clone, Debug, HashStable_Generic)] -pub enum ArrayLen { - Infer(HirId, Span), - Body(AnonConst), -} - -impl ArrayLen { - pub fn hir_id(&self) -> HirId { - match self { - &ArrayLen::Infer(hir_id, _) | &ArrayLen::Body(AnonConst { hir_id, .. }) => hir_id, - } - } -} - /// A constant (expression) that's not an item or associated item, /// but needs its own `DefId` for type-checking, const-eval, etc. /// These are usually found nested inside types (e.g., array lengths) @@ -2034,7 +2044,7 @@ pub enum ExprKind<'hir> { /// /// E.g., `[1; 5]`. The first expression is the element /// to be repeated; the second is the number of times to repeat it. - Repeat(&'hir Expr<'hir>, ArrayLen), + Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>), /// A suspension point for generators (i.e., `yield `). Yield(&'hir Expr<'hir>, YieldSource), @@ -2671,7 +2681,7 @@ pub enum TyKind<'hir> { /// A variable length slice (i.e., `[T]`). Slice(&'hir Ty<'hir>), /// A fixed length array (i.e., `[T; n]`). - Array(&'hir Ty<'hir>, ArrayLen), + Array(&'hir Ty<'hir>, &'hir ConstArg<'hir>), /// A raw pointer (i.e., `*const T` or `*mut T`). Ptr(MutTy<'hir>), /// A reference (i.e., `&'a T` or `&'a mut T`). @@ -3757,7 +3767,10 @@ impl<'hir> Node<'hir> { kind: ExprKind::ConstBlock(AnonConst { body, .. }) | ExprKind::Closure(Closure { body, .. }) - | ExprKind::Repeat(_, ArrayLen::Body(AnonConst { body, .. })), + | ExprKind::Repeat( + _, + ConstArg { kind: ConstArgKind::AnonConst(_, AnonConst { body, .. }) }, + ), .. }) => Some(*body), _ => None, @@ -4011,7 +4024,7 @@ mod size_asserts { static_assert_size!(FnDecl<'_>, 40); static_assert_size!(ForeignItem<'_>, 72); static_assert_size!(ForeignItemKind<'_>, 40); - static_assert_size!(GenericArg<'_>, 32); + static_assert_size!(GenericArg<'_>, 16); static_assert_size!(GenericBound<'_>, 48); static_assert_size!(Generics<'_>, 56); static_assert_size!(Impl<'_>, 80); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index df0047d82e12e..72a583ff59520 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -329,9 +329,6 @@ pub trait Visitor<'v>: Sized { fn visit_pat_field(&mut self, f: &'v PatField<'v>) { walk_pat_field(self, f) } - fn visit_array_length(&mut self, len: &'v ArrayLen) { - walk_array_len(self, len) - } fn visit_anon_const(&mut self, c: &'v AnonConst) { walk_anon_const(self, c) } @@ -347,10 +344,13 @@ pub trait Visitor<'v>: Sized { fn visit_ty(&mut self, t: &'v Ty<'v>) { walk_ty(self, t) } + fn visit_const_arg(&mut self, c: &'v ConstArg<'v>) { + walk_const_arg(self, c) + } fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) { walk_generic_param(self, p) } - fn visit_const_param_default(&mut self, _param: HirId, ct: &'v AnonConst) { + fn visit_const_param_default(&mut self, _param: HirId, ct: &'v ConstArg<'v>) { walk_const_param_default(self, ct) } fn visit_generics(&mut self, g: &'v Generics<'v>) { @@ -667,13 +667,6 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<' visitor.visit_pat(field.pat) } -pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) { - match len { - &ArrayLen::Infer(hir_id, _span) => visitor.visit_id(hir_id), - ArrayLen::Body(c) => visitor.visit_anon_const(c), - } -} - pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) { visitor.visit_id(constant.hir_id); visitor.visit_nested_body(constant.body); @@ -688,7 +681,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const), ExprKind::Repeat(ref element, ref count) => { visitor.visit_expr(element); - visitor.visit_array_length(count) + visitor.visit_const_arg(count); } ExprKind::Struct(ref qpath, fields, ref optional_base) => { visitor.visit_qpath(qpath, expression.hir_id, expression.span); @@ -838,7 +831,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) { } TyKind::Array(ref ty, ref length) => { visitor.visit_ty(ty); - visitor.visit_array_length(length) + visitor.visit_const_arg(length); } TyKind::TraitObject(bounds, ref lifetime, _syntax) => { for bound in bounds { @@ -851,6 +844,21 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) { } } +pub fn walk_const_arg<'v, V: Visitor<'v>>(visitor: &mut V, ct: &'v ConstArg<'v>) { + match &ct.kind { + ConstArgKind::AnonConst(_, ct) => { + visitor.visit_anon_const(ct); + } + ConstArgKind::Param(hir_id, qpath) => { + visitor.visit_id(*hir_id); + visitor.visit_qpath(qpath, *hir_id, qpath.span()) + } + ConstArgKind::Infer(hir_id, _) => { + visitor.visit_id(*hir_id); + } + } +} + pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam<'v>) { visitor.visit_id(param.hir_id); match param.name { @@ -869,8 +877,8 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi } } -pub fn walk_const_param_default<'v, V: Visitor<'v>>(visitor: &mut V, ct: &'v AnonConst) { - visitor.visit_anon_const(ct) +pub fn walk_const_param_default<'v, V: Visitor<'v>>(visitor: &mut V, ct: &'v ConstArg<'v>) { + visitor.visit_const_arg(ct) } pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) { @@ -1116,7 +1124,7 @@ pub fn walk_generic_arg<'v, V: Visitor<'v>>(visitor: &mut V, generic_arg: &'v Ge match generic_arg { GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt), GenericArg::Type(ty) => visitor.visit_ty(ty), - GenericArg::Const(ct) => visitor.visit_anon_const(&ct.value), + GenericArg::Const(ct) => visitor.visit_const_arg(ct), GenericArg::Infer(inf) => visitor.visit_infer(inf), } } diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index ed011b9086a19..bbe9fc976b514 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -107,10 +107,15 @@ fn generic_arg_mismatch_err( ); } } - (GenericArg::Const(cnst), GenericParamDefKind::Type { .. }) => { - let body = tcx.hir().body(cnst.value.body); - if let rustc_hir::ExprKind::Path(rustc_hir::QPath::Resolved(_, path)) = body.value.kind - { + (GenericArg::Const(cnst), GenericParamDefKind::Type { .. }) + if matches!(cnst.kind, hir::ConstArgKind::Param(_, _)) => + { + let path = match cnst.kind { + hir::ConstArgKind::Param(_, path) => path, + _ => unreachable!(), + }; + + if let rustc_hir::QPath::Resolved(_, path) = path { if let Res::Def(DefKind::Fn { .. }, id) = path.res { err.help(format!("`{}` is a function item, not a type", tcx.item_name(id))); err.help("function item types cannot be named directly"); diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 6ac1df6a07928..e77ad7b755705 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -15,6 +15,7 @@ use crate::errors::{ }; use crate::middle::resolve_bound_vars as rbv; use crate::require_c_abi_if_c_variadic; +use hir::def::CtorKind; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ @@ -34,7 +35,9 @@ use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{ + self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, UnevaluatedConst, +}; use rustc_middle::ty::{DynKind, ToPredicate}; use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS}; use rustc_span::edit_distance::find_best_match_for_name; @@ -59,6 +62,27 @@ pub struct PathSeg(pub DefId, pub usize); #[derive(Copy, Clone, Debug)] pub struct OnlySelfBounds(pub bool); +#[derive(Debug, Copy, Clone)] +pub enum ConstArgsParam { + Param(DefId), + ArrayLen, +} + +impl From for ConstArgsParam { + fn from(value: DefId) -> Self { + Self::Param(value) + } +} + +impl ConstArgsParam { + pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder> { + match self { + ConstArgsParam::Param(param_def_id) => tcx.type_of(param_def_id), + ConstArgsParam::ArrayLen => ty::EarlyBinder(tcx.types.usize), + } + } +} + pub trait AstConv<'tcx> { fn tcx(&self) -> TyCtxt<'tcx>; @@ -450,9 +474,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { handle_ty_args(has_default, &inf.to_ty()) } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { - let did = ct.value.def_id; - tcx.feed_anon_const_type(did, tcx.type_of(param.def_id)); - ty::Const::from_anon_const(tcx, did).into() + self.astconv.ast_const_to_const(ct, param.def_id).into() } (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => { let ty = tcx @@ -3326,12 +3348,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.at(span).type_of(def_id).subst(tcx, substs) } hir::TyKind::Array(ty, length) => { - let length = match length { - &hir::ArrayLen::Infer(_, span) => self.ct_infer(tcx.types.usize, None, span), - hir::ArrayLen::Body(constant) => { - ty::Const::from_anon_const(tcx, constant.def_id) - } - }; + let length = self.ast_const_to_const(length, ConstArgsParam::ArrayLen); tcx.mk_array_with_const_len(self.ast_ty_to_ty(ty), length) } @@ -3753,6 +3770,176 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } } + + pub fn ast_const_to_const( + &self, + ast_ct: &hir::ConstArg<'_>, + arg_param: impl Into, + ) -> Const<'tcx> { + self.ast_const_to_const_inner(ast_ct, arg_param.into()) + } + + #[instrument(level = "debug", skip(self), ret)] + fn ast_const_to_const_inner( + &self, + ast_ct: &hir::ConstArg<'_>, + arg_param: ConstArgsParam, + ) -> Const<'tcx> { + let tcx = self.tcx(); + + match ast_ct.kind { + hir::ConstArgKind::Infer(_, _) => { + self.ct_infer(arg_param.to_ty(tcx).subst_identity(), None, ast_ct.span()) + } + hir::ConstArgKind::AnonConst(_, ct) => { + tcx.feed_anon_const_type(ct.def_id, arg_param.to_ty(tcx)); + Const::from_anon_const(tcx, ct.def_id) + } + hir::ConstArgKind::Param(_, path) => match path { + hir::QPath::Resolved(_, path) => match path.res { + Res::Def(def_kind, def_id) => match def_kind { + DefKind::ConstParam => { + self.prohibit_generics(path.segments.iter(), |_| {}); + let param_ty = tcx.type_of(def_id).subst_identity(); + + match tcx.named_bound_var(ast_ct.hir_id()) { + Some(rbv::ResolvedArg::EarlyBound(_)) => { + // Find the name and index of the const parameter by indexing the generics of + // the parent item and construct a `ParamConst`. + let item_def_id = tcx.parent(def_id); + let generics = tcx.generics_of(item_def_id); + let index = generics.param_def_id_to_index[&def_id]; + let name = tcx.item_name(def_id); + tcx.mk_const(ty::ParamConst::new(index, name), param_ty) + } + Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => tcx + .mk_const( + ty::ConstKind::Bound( + debruijn, + ty::BoundVar::from_u32(index), + ), + param_ty, + ), + Some(rbv::ResolvedArg::Error(guar)) => { + tcx.const_error_with_guaranteed(param_ty, guar) + } + arg => bug!( + "unexpected bound var resolution for {:?}: {arg:?}", + ast_ct.hir_id() + ), + } + } + DefKind::Const => { + let (last, prev) = path.segments.split_last().unwrap(); + self.prohibit_generics(prev.iter(), |_| {}); + let substs = self.ast_path_substs_for_ty(ast_ct.span(), def_id, last); + tcx.mk_const( + UnevaluatedConst { def: def_id, substs }, + tcx.type_of(def_id).subst(tcx, substs), + ) + } + + DefKind::Fn | DefKind::Ctor(_, _) => { + let path_segs = self.def_ids_for_value_path_segments( + path.segments, + None, + def_kind, + def_id, + ast_ct.span(), + ); + + let generic_segs: FxHashSet<_> = + path_segs.iter().map(|&PathSeg(_, index)| index).collect(); + self.prohibit_generics( + path.segments.iter().enumerate().filter_map(|(n, segment)| { + if generic_segs.contains(&n) { Some(segment) } else { None } + }), + |_| {}, + ); + + let seg = path_segs.last().unwrap(); + let arg_segment = &path.segments[seg.1]; + + let substs = + self.ast_path_substs_for_ty(ast_ct.span(), seg.0, arg_segment); + + match def_kind { + DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => { + ty::Const::zero_sized( + tcx, + tcx.type_of(def_id).subst(tcx, substs), + ) + } + DefKind::Ctor(_, CtorKind::Const) => tcx.mk_const( + UnevaluatedConst { def: def_id, substs }, + tcx.type_of(def_id).subst(tcx, substs), + ), + _ => unreachable!(), + } + } + + DefKind::AssocFn | DefKind::AssocConst => { + unimplemented!("multi segment paths are not supported") + } + + // FIXME(const_arg_kind): somewhere else should be emitting this + DefKind::Static(_) => { + let e = tcx + .sess + .span_err(ast_ct.span(), "no static access in consts allowed"); + tcx.const_error_with_guaranteed(tcx.ty_error(e), e) + } + + DefKind::OpaqueTy + | DefKind::InlineConst + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::LifetimeParam + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::TyParam + | DefKind::ImplTraitPlaceholder + | DefKind::Field + | DefKind::GlobalAsm + | DefKind::Impl { .. } + | DefKind::Closure + | DefKind::Mod + | DefKind::Generator => bug!("unexpected path res of const arg"), + }, + + Res::SelfCtor(_) => todo!(), + + Res::Err + | Res::Local(_) + | Res::ToolMod + | Res::NonMacroAttr(_) + | Res::PrimTy(_) + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } => { + let e = tcx.sess.delay_span_bug( + ast_ct.span(), + format!("unexpected path res {:?} of const arg {:?}", path.res, ast_ct), + ); + tcx.const_error_with_guaranteed(tcx.ty_error(e), e) + } + }, + hir::QPath::TypeRelative(_, _) => { + bug!("multi-segment path consts are not yet supported") + } + hir::QPath::LangItem(_, _, _) => unimplemented!(), + }, + } + } } pub trait InferCtxtExt<'tcx> { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b65817ee95e92..94c002a86efd8 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -77,6 +77,7 @@ pub fn provide(providers: &mut Providers) { generator_kind, collect_mod_item_types, is_type_alias_impl_trait, + const_param_default, ..*providers }; } @@ -128,6 +129,12 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector { } intravisit::walk_ty(self, t) } + fn visit_const_arg(&mut self, c: &'v hir::ConstArg<'v>) { + if let hir::ConstArgKind::Infer(_, span) = c.kind { + self.0.push(span) + } + intravisit::walk_const_arg(self, c) + } fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) { match generic_arg { hir::GenericArg::Infer(inf) => { @@ -138,12 +145,6 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector { _ => {} } } - fn visit_array_length(&mut self, length: &'v hir::ArrayLen) { - if let &hir::ArrayLen::Infer(_, span) = length { - self.0.push(span); - } - intravisit::walk_array_len(self, length) - } } struct CollectItemTypesVisitor<'tcx> { @@ -291,7 +292,9 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { self.tcx.ensure().type_of(param.def_id); if let Some(default) = default { // need to store default and type of default - self.tcx.ensure().type_of(default.def_id); + if let hir::ConstArgKind::AnonConst(_, anon_ct) = default.kind { + self.tcx.ensure().type_of(anon_ct.def_id); + } self.tcx.ensure().const_param_default(param.def_id); } } @@ -1017,7 +1020,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool { Infer => true, Slice(ty) => is_suggestable_infer_ty(ty), Array(ty, length) => { - is_suggestable_infer_ty(ty) || matches!(length, hir::ArrayLen::Infer(_, _)) + is_suggestable_infer_ty(ty) || matches!(length.kind, hir::ConstArgKind::Infer(_, _)) } Tup(tys) => tys.iter().any(is_suggestable_infer_ty), Ptr(mut_ty) | Ref(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty), @@ -1488,3 +1491,19 @@ fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool _ => bug!("tried getting opaque_ty_origin for non-opaque: {:?}", def_id), } } + +fn const_param_default(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder> { + let item_def_id = tcx.parent(def_id.to_def_id()).expect_local(); + let item_ctxt = ItemCtxt::new(tcx, item_def_id); + + match tcx.hir().get_by_def_id(def_id) { + hir::Node::GenericParam(hir::GenericParam { + kind: hir::GenericParamKind::Const { default: Some(ac), .. }, + .. + }) => ty::EarlyBinder(item_ctxt.astconv().ast_const_to_const(ac, def_id.to_def_id())), + _ => span_bug!( + tcx.def_span(def_id), + "`const_param_default` expected a generic parameter with a constant" + ), + } +} diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index e04658c8e774e..f32cc0c06dad8 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -357,7 +357,7 @@ fn const_evaluatable_predicates_of( } } - fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::AnonConst) { + fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::ConstArg<'tcx>) { // Do not look into const param defaults, // these get checked when they are actually instantiated. // diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 5c7f7f10b17ec..5a50678f32bf2 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -918,8 +918,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } GenericParamKind::Const { ty, default } => { this.visit_ty(ty); - if let Some(default) = default { - this.visit_body(this.tcx.hir().body(default.body)); + if let Some(arg) = default { + this.visit_const_arg(arg); } } } @@ -1588,7 +1588,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { i += 1; } GenericArg::Const(ct) => { - self.visit_anon_const(&ct.value); + self.visit_const_arg(ct); i += 1; } GenericArg::Infer(inf) => { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 8df0166f76b4b..b60f76afcffbf 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -63,7 +63,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { def_id: param_def_id, kind: GenericParamKind::Const { default: Some(ct), .. }, .. - }) if ct.hir_id == hir_id => { + }) if ct.hir_id() == hir_id => { return tcx.type_of(param_def_id) .no_bound_vars() .expect("const parameter types cannot be generic") diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index d93e8efc1b59a..78b957862ee2a 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -350,7 +350,7 @@ impl<'a> State<'a> { self.word("["); self.print_type(ty); self.word("; "); - self.print_array_length(length); + self.print_const_arg(length); self.word("]"); } hir::TyKind::Typeof(ref e) => { @@ -370,6 +370,17 @@ impl<'a> State<'a> { self.end() } + pub fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) { + self.maybe_print_comment(const_arg.span().lo()); + self.ibox(0); + match &const_arg.kind { + hir::ConstArgKind::AnonConst(_, ct) => self.print_anon_const(ct), + hir::ConstArgKind::Param(_, path) => self.print_qpath(path, false), + hir::ConstArgKind::Infer(_, _) => self.word("_"), + } + self.end(); + } + pub fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) { self.hardbreak_if_not_bol(); self.maybe_print_comment(item.span.lo()); @@ -1018,13 +1029,6 @@ impl<'a> State<'a> { self.print_else(elseopt) } - pub fn print_array_length(&mut self, len: &hir::ArrayLen) { - match len { - hir::ArrayLen::Infer(_, _) => self.word("_"), - hir::ArrayLen::Body(ct) => self.print_anon_const(ct), - } - } - pub fn print_anon_const(&mut self, constant: &hir::AnonConst) { self.ann.nested(self, Nested::Body(constant.body)) } @@ -1102,12 +1106,12 @@ impl<'a> State<'a> { self.end() } - fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::ArrayLen) { + fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::ConstArg<'_>) { self.ibox(INDENT_UNIT); self.word("["); self.print_expr(element); self.word_space(";"); - self.print_array_length(count); + self.print_const_arg(count); self.word("]"); self.end() } @@ -1708,7 +1712,7 @@ impl<'a> State<'a> { GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt), GenericArg::Lifetime(_) => {} GenericArg::Type(ty) => s.print_type(ty), - GenericArg::Const(ct) => s.print_anon_const(&ct.value), + GenericArg::Const(ct) => s.print_const_arg(ct), GenericArg::Infer(_inf) => s.word("_"), } }); @@ -2164,7 +2168,7 @@ impl<'a> State<'a> { if let Some(default) = default { self.space(); self.word_space("="); - self.print_anon_const(default); + self.print_const_arg(default); } } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bba049c381934..e571a36046fe6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -33,6 +33,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, HirId, QPath}; use rustc_hir_analysis::astconv::AstConv as _; +use rustc_hir_analysis::astconv::ConstArgsParam; use rustc_hir_analysis::check::ty_kind_suggestion; use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -1347,7 +1348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return }; if let hir::TyKind::Array(_, length) = ty.peel_refs().kind - && let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length + && let hir::ConstArgKind::AnonConst(_, hir::AnonConst { hir_id, .. }) = length.kind && let Some(span) = self.tcx.hir().opt_span(hir_id) { match self.tcx.sess.diagnostic().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) { @@ -1387,12 +1388,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_expr_repeat( &self, element: &'tcx hir::Expr<'tcx>, - count: &'tcx hir::ArrayLen, + count: &'tcx hir::ConstArg<'_>, expected: Expectation<'tcx>, expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; - let count = self.array_length_to_const(count); + let count = self.const_arg_to_const(count, ConstArgsParam::ArrayLen); if let Some(count) = count.try_eval_target_usize(tcx, self.param_env) { self.suggest_array_len(expr, count); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9e78e6acba54b..f920219b63400 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -14,8 +14,8 @@ use rustc_hir_analysis::astconv::generics::{ check_generic_arg_count_for_call, create_substs_for_generic_args, }; use rustc_hir_analysis::astconv::{ - AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch, - GenericArgCountResult, IsMethodCall, PathSeg, + AstConv, ConstArgsParam, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, + GenericArgCountMismatch, GenericArgCountResult, IsMethodCall, PathSeg, }; use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; @@ -403,32 +403,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn array_length_to_const(&self, length: &hir::ArrayLen) -> ty::Const<'tcx> { - match length { - &hir::ArrayLen::Infer(_, span) => self.ct_infer(self.tcx.types.usize, None, span), - hir::ArrayLen::Body(anon_const) => { - let span = self.tcx.def_span(anon_const.def_id); - let c = ty::Const::from_anon_const(self.tcx, anon_const.def_id); - self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None)); - self.normalize(span, c) - } - } - } - pub fn const_arg_to_const( &self, - ast_c: &hir::AnonConst, - param_def_id: DefId, + ast_c: &hir::ConstArg<'_>, + args_param: impl Into, ) -> ty::Const<'tcx> { - let did = ast_c.def_id; - self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id)); - let c = ty::Const::from_anon_const(self.tcx, did); - self.register_wf_obligation( - c.into(), - self.tcx.hir().span(ast_c.hir_id), - ObligationCauseCode::WellFormed(None), - ); - c + let ct = self.astconv().ast_const_to_const(ast_c, args_param); + self.register_wf_obligation(ct.into(), ast_c.span(), ObligationCauseCode::WellFormed(None)); + ct } // If the type given by the user has free regions, save it for later, since @@ -1271,7 +1253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.to_ty(ty).raw.into() } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { - self.fcx.const_arg_to_const(&ct.value, param.def_id).into() + self.fcx.const_arg_to_const(ct, param.def_id).into() } (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { self.fcx.ty_infer(Some(param), inf.span).into() diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 9155a3d8daa19..5b5c3cacac20f 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -377,7 +377,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self.cfcx.to_ty(ty).raw.into() } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { - self.cfcx.const_arg_to_const(&ct.value, param.def_id).into() + self.cfcx.const_arg_to_const(ct, param.def_id).into() } (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { self.cfcx.ty_infer(Some(param), inf.span).into() diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index ce70f39cc4014..e8f92e787717e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2058,7 +2058,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; if let Some(tykind) = tykind && let hir::TyKind::Array(_, length) = tykind - && let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length + && let hir::ConstArg { kind: hir::ConstArgKind::AnonConst(_, hir::AnonConst { hir_id, ..})} = length && let Some(span) = self.tcx.hir().opt_span(*hir_id) { Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { span, length: sz.found }) diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index 2bb2a3aab5527..758a090e44a29 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -73,9 +73,12 @@ fn gen_args(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> String { GenericArg::Type(ty) => { cx.tcx.sess.source_map().span_to_snippet(ty.span).unwrap_or_else(|_| "_".into()) } - GenericArg::Const(c) => { - cx.tcx.sess.source_map().span_to_snippet(c.span).unwrap_or_else(|_| "_".into()) - } + GenericArg::Const(c) => cx + .tcx + .sess + .source_map() + .span_to_snippet(c.span()) + .unwrap_or_else(|_| "_".into()), GenericArg::Infer(_) => String::from("_"), }) .collect::>(); diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index e7107c28bf407..928fbdef7f714 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,9 +1,7 @@ -use crate::middle::resolve_bound_vars as rbv; use crate::mir::interpret::LitToConstInput; use crate::ty::{self, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_data_structures::intern::Interned; use rustc_hir as hir; -use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_macros::HashStable; use std::fmt; @@ -51,7 +49,7 @@ impl<'tcx> Const<'tcx> { self.0.kind } - /// Literals and const generic parameters are eagerly converted to a constant, everything else + /// Literals are eagerly converted to a constant, everything else /// becomes `Unevaluated`. #[instrument(skip(tcx), level = "debug")] pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { @@ -68,7 +66,7 @@ impl<'tcx> Const<'tcx> { let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic"); - match Self::try_eval_lit_or_param(tcx, ty, expr) { + match Self::try_eval_lit(tcx, ty, expr) { Some(v) => v, None => tcx.mk_const( ty::UnevaluatedConst { @@ -81,12 +79,8 @@ impl<'tcx> Const<'tcx> { } #[instrument(skip(tcx), level = "debug")] - fn try_eval_lit_or_param( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, - expr: &'tcx hir::Expr<'tcx>, - ) -> Option { - // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments + fn try_eval_lit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) -> Option { + // Unwrap a block, so that e.g. `{ 1 }` is recognised as a literal. 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() => { @@ -119,37 +113,7 @@ impl<'tcx> Const<'tcx> { } } } - - match expr.kind { - hir::ExprKind::Path(hir::QPath::Resolved( - _, - &hir::Path { res: Res::Def(DefKind::ConstParam, def_id), .. }, - )) => { - // Use the type from the param's definition, since we can resolve it, - // not the expected parameter type from WithOptConstParam. - let param_ty = tcx.type_of(def_id).subst_identity(); - match tcx.named_bound_var(expr.hir_id) { - Some(rbv::ResolvedArg::EarlyBound(_)) => { - // Find the name and index of the const parameter by indexing the generics of - // the parent item and construct a `ParamConst`. - let item_def_id = tcx.parent(def_id); - let generics = tcx.generics_of(item_def_id); - let index = generics.param_def_id_to_index[&def_id]; - let name = tcx.item_name(def_id); - Some(tcx.mk_const(ty::ParamConst::new(index, name), param_ty)) - } - Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => Some(tcx.mk_const( - ty::ConstKind::Bound(debruijn, ty::BoundVar::from_u32(index)), - param_ty, - )), - Some(rbv::ResolvedArg::Error(guar)) => { - Some(tcx.const_error_with_guaranteed(param_ty, guar)) - } - arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id), - } - } - _ => None, - } + None } /// Panics if self.kind != ty::ConstKind::Value @@ -254,17 +218,3 @@ impl<'tcx> Const<'tcx> { matches!(self.kind(), ty::ConstKind::Infer(_)) } } - -pub fn const_param_default(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder> { - let default_def_id = match tcx.hir().get_by_def_id(def_id) { - hir::Node::GenericParam(hir::GenericParam { - kind: hir::GenericParamKind::Const { default: Some(ac), .. }, - .. - }) => ac.def_id, - _ => span_bug!( - tcx.def_span(def_id), - "`const_param_default` expected a generic parameter with a constant" - ), - }; - ty::EarlyBinder(Const::from_anon_const(tcx, default_def_id)) -} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f882f54d62811..76d5c1abe1375 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2590,7 +2590,6 @@ pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { trait_impls_of: trait_def::trait_impls_of_provider, incoherent_impls: trait_def::incoherent_impls_provider, - const_param_default: consts::const_param_default, vtable_allocation: vtable::vtable_allocation_provider, ..*providers }; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 926172ff828c7..a1aa76fc1ca5d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1344,7 +1344,7 @@ pub trait PrettyPrinter<'tcx>: match ct.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => { match self.tcx().def_kind(def) { - DefKind::Const | DefKind::AssocConst => { + DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst => { p!(print_value_path(def, substs)) } DefKind::AnonConst => { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 277237a5515a4..6e117f2726798 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -215,7 +215,7 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { } impl<'tcx> Visitor<'tcx> for GatherCtors<'_> { fn visit_variant_data(&mut self, v: &'tcx hir::VariantData<'tcx>) { - if let hir::VariantData::Tuple(_, _, def_id) = *v { + if let hir::VariantData::Tuple(_, _, def_id) | hir::VariantData::Unit(_, def_id) = *v { self.set.insert(def_id); } intravisit::walk_struct_def(self, v) diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 19d07fab0b954..c50e912c705f2 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -1,3 +1,4 @@ +use hir::def::{CtorKind, CtorOf, DefKind}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; @@ -834,27 +835,40 @@ fn build_call_shim<'tcx>( } pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { - debug_assert!(tcx.is_constructor(ctor_id)); - let param_env = tcx.param_env_reveal_all_normalized(ctor_id); + let span = tcx.def_span(ctor_id); - // Normalize the sig. - let sig = tcx - .fn_sig(ctor_id) - .subst_identity() - .no_bound_vars() - .expect("LBR in ADT constructor signature"); - let sig = tcx.normalize_erasing_regions(param_env, sig); + let (local_decls, inputs, adt_ty) = match tcx.def_kind(ctor_id) { + DefKind::Ctor(_, CtorKind::Fn) => { + // Normalize the sig. + let sig = tcx + .fn_sig(ctor_id) + .subst_identity() + .no_bound_vars() + .expect("LBR in ADT constructor signature"); + let sig = tcx.normalize_erasing_regions(param_env, sig); + debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig); + + (local_decls_for_sig(&sig, span), sig.inputs().len(), sig.output()) + } + DefKind::Ctor(of, CtorKind::Const) => { + let mut ctor_id = ctor_id; + if let CtorOf::Variant = of { + ctor_id = tcx.parent(ctor_id); + } + let adt = tcx.parent(ctor_id); + let adt_ty = + tcx.normalize_erasing_regions(param_env, tcx.type_of(adt).subst_identity()); - let ty::Adt(adt_def, substs) = sig.output().kind() else { - bug!("unexpected type for ADT ctor {:?}", sig.output()); + let local_decls = std::iter::once(LocalDecl::new(adt_ty, span)).collect(); + (local_decls, 0, adt_ty) + } + def_kind => bug!("ctor_id {:?} was expected to be a `DefKind::Ctor`", def_kind), }; - debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig); - - let span = tcx.def_span(ctor_id); - - let local_decls = local_decls_for_sig(&sig, span); + let ty::Adt(adt_def, substs) = adt_ty.kind() else { + bug!("unexpected type for ADT ctor {:?}", adt_ty); + }; let source_info = SourceInfo::outermost(span); @@ -891,13 +905,7 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { }; let source = MirSource::item(ctor_id); - let body = new_body( - source, - IndexVec::from_elem_n(start_block, 1), - local_decls, - sig.inputs().len(), - span, - ); + let body = new_body(source, IndexVec::from_elem_n(start_block, 1), local_decls, inputs, span); crate::pass_manager::dump_mir_for_phase_change(tcx, &body); diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index dc5e454074ded..2abd2be3d904a 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -434,7 +434,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { match ga { hir::GenericArg::Lifetime(lt) => self.visit_lifetime(lt), hir::GenericArg::Type(ty) => self.visit_ty(ty), - hir::GenericArg::Const(ct) => self.visit_anon_const(&ct.value), + hir::GenericArg::Const(ct) => self.visit_const_arg(ct), hir::GenericArg::Infer(inf) => self.visit_infer(inf), } } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 356d7f365fe71..2c7184b403932 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -219,6 +219,14 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { // // In that case, the impl-trait is lowered as an additional generic parameter. self.with_impl_trait(ImplTraitContext::Universal(self.parent_def), |this| { + if let GenericParamKind::Const { kw_span: _, ty, default: Some(ct) } = ¶m.kind { + this.visit_ty(ty); + match ct.value.is_potential_trivial_const_arg() { + Some(_) => visit::walk_anon_const(this, ct), + None => this.visit_anon_const(ct), + } + return; + } visit::walk_generic_param(this, param) }); } @@ -241,15 +249,26 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { } } + fn visit_generic_arg(&mut self, generic_arg: &'a GenericArg) { + if let GenericArg::Const(anon_ct) = generic_arg { + if anon_ct.value.is_potential_trivial_const_arg().is_some() { + visit::walk_anon_const(self, &anon_ct); + return; + } + } + visit::walk_generic_arg(self, generic_arg); + } + fn visit_anon_const(&mut self, constant: &'a AnonConst) { let def = self.create_def(constant.id, DefPathData::AnonConst, constant.value.span); + debug!(?constant, ?def); self.with_parent(def, |this| visit::walk_anon_const(this, constant)); } fn visit_expr(&mut self, expr: &'a Expr) { - let parent_def = match expr.kind { + let parent_def = match &expr.kind { ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id), - ExprKind::Closure(ref closure) => { + ExprKind::Closure(closure) => { // Async closures desugar to closures inside of closures, so // we must create two defs. let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span); @@ -261,6 +280,14 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { } } ExprKind::Async(_, _) => self.create_def(expr.id, DefPathData::ClosureExpr, expr.span), + ExprKind::Repeat(expr, length) => match length.value.is_potential_trivial_const_arg() { + Some(_) => { + self.visit_expr(expr); + visit::walk_anon_const(self, length); + return; + } + None => self.parent_def, + }, _ => self.parent_def, }; @@ -268,8 +295,15 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { } fn visit_ty(&mut self, ty: &'a Ty) { - match ty.kind { + match &ty.kind { TyKind::MacCall(..) => self.visit_macro_invoc(ty.id), + TyKind::Array(ty, length) => { + self.visit_ty(ty); + match length.value.is_potential_trivial_const_arg() { + Some(_) => visit::walk_anon_const(self, length), + None => self.visit_anon_const(length), + }; + } _ => visit::walk_ty(self, ty), } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2a8287d5554f8..3aeae1c9736bc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3972,7 +3972,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ); self.resolve_anon_const_manual( - constant.value.is_potential_trivial_const_arg(), + constant.value.is_potential_trivial_const_arg().is_some(), anon_const_kind, |this| this.resolve_expr(&constant.value, None), ) @@ -4118,7 +4118,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // that is how they will be later lowered to HIR. if const_args.contains(&idx) { self.resolve_anon_const_manual( - argument.is_potential_trivial_const_arg(), + argument.is_potential_trivial_const_arg().is_some(), AnonConstKind::ConstArg(IsRepeatExpr::No), |this| this.resolve_expr(argument, None), ); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 086ab32b52007..c16921ed2bed3 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -608,8 +608,23 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { self.require_sized(subty, traits::SliceOrArrayElem); } - ty::Array(subty, _) => { + ty::Array(subty, length) => { self.require_sized(subty, traits::SliceOrArrayElem); + + if !length.has_escaping_bound_vars() { + let predicate = ty::Binder::dummy(ty::PredicateKind::Clause( + ty::Clause::ConstArgHasType(length, self.tcx().types.usize), + )); + let cause = self.cause(traits::WellFormed(None)); + self.out.push(traits::Obligation::with_depth( + self.tcx(), + cause, + self.recursion_depth, + self.param_env, + predicate, + )); + } + // Note that we handle the len is implicitly checked while walking `arg`. } diff --git a/tests/ui/closures/issue-52437.rs b/tests/ui/closures/issue-52437.rs index 6ac5380a5aa23..9dd23a29a4871 100644 --- a/tests/ui/closures/issue-52437.rs +++ b/tests/ui/closures/issue-52437.rs @@ -2,4 +2,5 @@ fn main() { [(); &(&'static: loop { |x| {}; }) as *const _ as usize] //~^ ERROR: invalid label name `'static` //~| ERROR: type annotations needed + //~| ERROR: mismatched types } diff --git a/tests/ui/closures/issue-52437.stderr b/tests/ui/closures/issue-52437.stderr index 9ba24c7a88695..2a2ed558e54a9 100644 --- a/tests/ui/closures/issue-52437.stderr +++ b/tests/ui/closures/issue-52437.stderr @@ -15,6 +15,15 @@ help: consider giving this closure parameter an explicit type LL | [(); &(&'static: loop { |x: /* Type */| {}; }) as *const _ as usize] | ++++++++++++ -error: aborting due to 2 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 `[(); &(&'static: loop { |x| {}; }) as *const _ as usize]` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/const-generics/bad-generic-in-copy-impl.rs b/tests/ui/const-generics/bad-generic-in-copy-impl.rs index b5663464cf422..0ecb316d19a9f 100644 --- a/tests/ui/const-generics/bad-generic-in-copy-impl.rs +++ b/tests/ui/const-generics/bad-generic-in-copy-impl.rs @@ -1,7 +1,7 @@ #[derive(Copy, Clone)] pub struct Foo { x: [u8; SIZE], - //~^ ERROR mismatched types + //~^ ERROR the constant `1` is not of type `usize` } const SIZE: u32 = 1; diff --git a/tests/ui/const-generics/bad-generic-in-copy-impl.stderr b/tests/ui/const-generics/bad-generic-in-copy-impl.stderr index 25701ce68ccc8..bda21f697bda6 100644 --- a/tests/ui/const-generics/bad-generic-in-copy-impl.stderr +++ b/tests/ui/const-generics/bad-generic-in-copy-impl.stderr @@ -1,9 +1,8 @@ -error[E0308]: mismatched types - --> $DIR/bad-generic-in-copy-impl.rs:3:13 +error: the constant `1` is not of type `usize` + --> $DIR/bad-generic-in-copy-impl.rs:3:8 | LL | x: [u8; SIZE], - | ^^^^ expected `usize`, found `u32` + | ^^^^^^^^^^ expected `usize`, found `u32` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/bad-subst-const-kind.rs b/tests/ui/const-generics/bad-subst-const-kind.rs index e13dfbacd2422..f16e130251d86 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.rs +++ b/tests/ui/const-generics/bad-subst-const-kind.rs @@ -6,7 +6,7 @@ trait Q { } impl Q for [u8; N] { - //~^ ERROR mismatched types + //~^ ERROR the constant `N` is not of type `usize` const ASSOC: usize = 1; } diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr index bd24f9140e4ea..f4077b3e09450 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.stderr +++ b/tests/ui/const-generics/bad-subst-const-kind.stderr @@ -1,9 +1,8 @@ -error[E0308]: mismatched types - --> $DIR/bad-subst-const-kind.rs:8:31 +error: the constant `N` is not of type `usize` + --> $DIR/bad-subst-const-kind.rs:8:26 | LL | impl Q for [u8; N] { - | ^ expected `usize`, found `u64` + | ^^^^^^^ expected `usize`, found `u64` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr index f829526ca1dc8..2b44265a137d6 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr @@ -14,7 +14,7 @@ LL | pub struct SelfDependent; | = note: const parameters may not be used in the type of const parameters -error: `[u8; N]` is forbidden as the type of a const generic parameter +error: `[u8; [const error]]` is forbidden as the type of a const generic parameter --> $DIR/const-param-type-depends-on-const-param.rs:11:47 | LL | pub struct Dependent([(); N]); @@ -23,7 +23,7 @@ LL | pub struct Dependent([(); N]); = note: the only supported types are integers, `bool` and `char` = help: more complex types are supported with `#![feature(adt_const_params)]` -error: `[u8; N]` is forbidden as the type of a const generic parameter +error: `[u8; [const error]]` is forbidden as the type of a const generic parameter --> $DIR/const-param-type-depends-on-const-param.rs:15:35 | LL | pub struct SelfDependent; diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.rs b/tests/ui/const-generics/const-param-type-depends-on-const-param.rs index 64b2acb036292..ebdd3962603a9 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.rs +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.rs @@ -10,10 +10,10 @@ pub struct Dependent([(); N]); //~^ ERROR: the type of const parameters must not depend on other generic parameters -//[min]~^^ ERROR `[u8; N]` is forbidden +//[min]~^^ ERROR `[u8; [const error]]` is forbidden pub struct SelfDependent; //~^ ERROR: the type of const parameters must not depend on other generic parameters -//[min]~^^ ERROR `[u8; N]` is forbidden +//[min]~^^ ERROR `[u8; [const error]]` is forbidden fn main() {} diff --git a/tests/ui/const-generics/issue-97007.rs b/tests/ui/const-generics/issue-97007.rs index 7036834c4b119..3ef4697330874 100644 --- a/tests/ui/const-generics/issue-97007.rs +++ b/tests/ui/const-generics/issue-97007.rs @@ -1,4 +1,6 @@ -// check-pass +// known-bug: unknown +// this should pass but currently does not because `generic_const_exprs` is very prone +// to randomly encountering cycle errors on well formed code. #![feature(adt_const_params, generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/issue-97007.stderr b/tests/ui/const-generics/issue-97007.stderr new file mode 100644 index 0000000000000..8e22931ea2b80 --- /dev/null +++ b/tests/ui/const-generics/issue-97007.stderr @@ -0,0 +1,28 @@ +error[E0391]: cycle detected when building an abstract representation for `lib::::proceed_to::{constant#0}` + --> $DIR/issue-97007.rs:58:25 + | +LL | ) -> Walk { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires building THIR for `lib::::proceed_to::{constant#0}`... + --> $DIR/issue-97007.rs:58:25 + | +LL | ) -> Walk { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires type-checking `lib::::proceed_to::{constant#0}`... + --> $DIR/issue-97007.rs:58:25 + | +LL | ) -> Walk { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires building an abstract representation for `lib::::proceed_to::{constant#0}`, completing the cycle +note: cycle used when checking that `lib::::proceed_to` is well-formed + --> $DIR/issue-97007.rs:56:9 + | +LL | / pub fn proceed_to( +LL | | self, +LL | | ) -> Walk { + | |___________________________________________________________^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index 9c0e5179cc4c2..45ccb9581fbec 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -6,7 +6,7 @@ LL | fn foo() {} | = note: const parameters may not be used in the type of const parameters -error: `[u8; N]` is forbidden as the type of a const generic parameter +error: `[u8; [const error]]` is forbidden as the type of a const generic parameter --> $DIR/issue-62878.rs:5:33 | LL | fn foo() {} diff --git a/tests/ui/const-generics/issues/issue-62878.rs b/tests/ui/const-generics/issues/issue-62878.rs index 4c08a484ef47b..4935dfb107a01 100644 --- a/tests/ui/const-generics/issues/issue-62878.rs +++ b/tests/ui/const-generics/issues/issue-62878.rs @@ -4,7 +4,7 @@ fn foo() {} //~^ ERROR the type of const parameters must not -//[min]~| ERROR `[u8; N]` is forbidden as the type of a const generic parameter +//[min]~| ERROR `[u8; [const error]]` is forbidden as the type of a const generic parameter fn main() { foo::<_, { [1] }>(); diff --git a/tests/ui/const-generics/issues/issue-71169.min.stderr b/tests/ui/const-generics/issues/issue-71169.min.stderr index ebfb24bec28df..edbcb047fb0f7 100644 --- a/tests/ui/const-generics/issues/issue-71169.min.stderr +++ b/tests/ui/const-generics/issues/issue-71169.min.stderr @@ -6,7 +6,7 @@ LL | fn foo() {} | = note: const parameters may not be used in the type of const parameters -error: `[u8; LEN]` is forbidden as the type of a const generic parameter +error: `[u8; [const error]]` is forbidden as the type of a const generic parameter --> $DIR/issue-71169.rs:5:38 | LL | fn foo() {} diff --git a/tests/ui/const-generics/issues/issue-71169.rs b/tests/ui/const-generics/issues/issue-71169.rs index e4ec6b0737613..72490bbd1fc4c 100644 --- a/tests/ui/const-generics/issues/issue-71169.rs +++ b/tests/ui/const-generics/issues/issue-71169.rs @@ -4,7 +4,7 @@ fn foo() {} //~^ ERROR the type of const parameters must not -//[min]~^^ ERROR `[u8; LEN]` is forbidden as the type of a const generic parameter +//[min]~^^ ERROR `[u8; [const error]]` is forbidden as the type of a const generic parameter fn main() { const DATA: [u8; 4] = *b"ABCD"; foo::<4, DATA>(); diff --git a/tests/ui/const-generics/transmute-fail-2.rs b/tests/ui/const-generics/transmute-fail-2.rs new file mode 100644 index 0000000000000..db8c6b94d0bf1 --- /dev/null +++ b/tests/ui/const-generics/transmute-fail-2.rs @@ -0,0 +1,12 @@ +#![feature(transmute_generic_consts)] +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { + //~^ ERROR the constant `W` is not of type `usize` + unsafe { + std::mem::transmute(v) + } +} + +fn main() {} diff --git a/tests/ui/const-generics/transmute-fail-2.stderr b/tests/ui/const-generics/transmute-fail-2.stderr new file mode 100644 index 0000000000000..94997450186f3 --- /dev/null +++ b/tests/ui/const-generics/transmute-fail-2.stderr @@ -0,0 +1,8 @@ +error: the constant `W` is not of type `usize` + --> $DIR/transmute-fail-2.rs:5:42 + | +LL | fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { + | ^^^^^^^^^^^^^ expected `usize`, found `bool` + +error: aborting due to previous error + diff --git a/tests/ui/const-generics/transmute-fail.rs b/tests/ui/const-generics/transmute-fail.rs index d7bf1b47fb5a7..4f2d39c96dac2 100644 --- a/tests/ui/const-generics/transmute-fail.rs +++ b/tests/ui/const-generics/transmute-fail.rs @@ -9,15 +9,6 @@ fn foo(v: [[u32;H+1]; W]) -> [[u32; W+1]; H] { } } -fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { - //~^ ERROR mismatched types - //~| ERROR mismatched types - unsafe { - std::mem::transmute(v) - //~^ ERROR cannot transmute between types - } -} - fn baz(v: [[u32; H]; W]) -> [u32; W * H * H] { unsafe { std::mem::transmute(v) diff --git a/tests/ui/const-generics/transmute-fail.stderr b/tests/ui/const-generics/transmute-fail.stderr index 41b098135e81e..65aff45acca6a 100644 --- a/tests/ui/const-generics/transmute-fail.stderr +++ b/tests/ui/const-generics/transmute-fail.stderr @@ -8,28 +8,7 @@ LL | std::mem::transmute(v) = note: target type: `[[u32; W+1]; H]` (generic size [const expr]) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:16:5 - | -LL | std::mem::transmute(v) - | ^^^^^^^^^^^^^^^^^^^ - | - = note: source type: `[[u32; H]; W]` (this type does not have a fixed size) - = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W]) - -error[E0308]: mismatched types - --> $DIR/transmute-fail.rs:12:53 - | -LL | fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { - | ^ expected `usize`, found `bool` - -error[E0308]: mismatched types - --> $DIR/transmute-fail.rs:12:67 - | -LL | fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { - | ^ expected `usize`, found `bool` - -error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:23:5 + --> $DIR/transmute-fail.rs:14:5 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -38,7 +17,7 @@ LL | std::mem::transmute(v) = note: target type: `[u32; W * H * H]` (generic size [const expr]) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:30:5 + --> $DIR/transmute-fail.rs:21:5 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -46,7 +25,6 @@ LL | std::mem::transmute(v) = note: source type: `[[[u32; 8888888]; 9999999]; 777777777]` (values of the type `[[[u32; 8888888]; 9999999]; 777777777]` are too big for the current architecture) = note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type `[[[u32; 9999999]; 777777777]; 8888888]` are too big for the current architecture) -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0308, E0512. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/const-generics/type_mismatch.rs b/tests/ui/const-generics/type_mismatch.rs index daa13277be0a0..3cec21591999a 100644 --- a/tests/ui/const-generics/type_mismatch.rs +++ b/tests/ui/const-generics/type_mismatch.rs @@ -1,10 +1,8 @@ fn foo() -> [u8; N] { - bar::() //~ ERROR mismatched types - //~^ ERROR the constant `N` is not of type `u8` + bar::() } fn bar() -> [u8; N] {} -//~^ ERROR mismatched types -//~| ERROR mismatched types +//~^ ERROR the constant `N` is not of type `usize` fn main() {} diff --git a/tests/ui/const-generics/type_mismatch.stderr b/tests/ui/const-generics/type_mismatch.stderr index 394dd44d40d33..6402e69fba89f 100644 --- a/tests/ui/const-generics/type_mismatch.stderr +++ b/tests/ui/const-generics/type_mismatch.stderr @@ -1,35 +1,8 @@ -error: the constant `N` is not of type `u8` - --> $DIR/type_mismatch.rs:2:11 - | -LL | bar::() - | ^ expected `u8`, found `usize` - | -note: required by a bound in `bar` - --> $DIR/type_mismatch.rs:6:8 - | -LL | fn bar() -> [u8; N] {} - | ^^^^^^^^^^^ required by this bound in `bar` - -error[E0308]: mismatched types - --> $DIR/type_mismatch.rs:2:11 - | -LL | bar::() - | ^ expected `u8`, found `usize` - -error[E0308]: mismatched types - --> $DIR/type_mismatch.rs:6:26 - | -LL | fn bar() -> [u8; N] {} - | --- ^^^^^^^ expected `[u8; N]`, found `()` - | | - | implicitly returns `()` as its body has no tail or `return` expression - -error[E0308]: mismatched types - --> $DIR/type_mismatch.rs:6:31 +error: the constant `N` is not of type `usize` + --> $DIR/type_mismatch.rs:5:26 | LL | fn bar() -> [u8; N] {} - | ^ expected `usize`, found `u8` + | ^^^^^^^ expected `usize`, found `u8` -error: aborting due to 4 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-integer-bool-ops.rs b/tests/ui/consts/const-integer-bool-ops.rs index 4110ae3e45692..35915a7a606a4 100644 --- a/tests/ui/consts/const-integer-bool-ops.rs +++ b/tests/ui/consts/const-integer-bool-ops.rs @@ -6,7 +6,6 @@ const X: usize = 42 && 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR: [i32; X] = [99; 34]; -//~^ constant const X1: usize = 42 || 39; //~^ ERROR mismatched types @@ -16,7 +15,6 @@ const X1: usize = 42 || 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR1: [i32; X1] = [99; 47]; -//~^ constant const X2: usize = -42 || -39; //~^ ERROR mismatched types @@ -26,7 +24,6 @@ const X2: usize = -42 || -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR2: [i32; X2] = [99; 18446744073709551607]; -//~^ constant const X3: usize = -42 && -39; //~^ ERROR mismatched types @@ -36,43 +33,36 @@ const X3: usize = -42 && -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR3: [i32; X3] = [99; 6]; -//~^ constant const Y: usize = 42.0 == 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR: [i32; Y] = [99; 1]; -//~^ constant const Y1: usize = 42.0 >= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR1: [i32; Y1] = [99; 1]; -//~^ constant const Y2: usize = 42.0 <= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR2: [i32; Y2] = [99; 1]; -//~^ constant const Y3: usize = 42.0 > 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR3: [i32; Y3] = [99; 0]; -//~^ constant const Y4: usize = 42.0 < 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR4: [i32; Y4] = [99; 0]; -//~^ constant const Y5: usize = 42.0 != 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR5: [i32; Y5] = [99; 0]; -//~^ constant fn main() { let _ = ARR; diff --git a/tests/ui/consts/const-integer-bool-ops.stderr b/tests/ui/consts/const-integer-bool-ops.stderr index b5c3b22fdbe36..4e503e5a5c0a4 100644 --- a/tests/ui/consts/const-integer-bool-ops.stderr +++ b/tests/ui/consts/const-integer-bool-ops.stderr @@ -16,156 +16,96 @@ error[E0308]: mismatched types LL | const X: usize = 42 && 39; | ^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:8:18 - | -LL | const ARR: [i32; X] = [99; 34]; - | ^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:25 + --> $DIR/const-integer-bool-ops.rs:10:25 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:18:19 - | -LL | const ARR1: [i32; X1] = [99; 47]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:26 + --> $DIR/const-integer-bool-ops.rs:19:26 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:28:19 - | -LL | const ARR2: [i32; X2] = [99; 18446744073709551607]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 + --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:26 + --> $DIR/const-integer-bool-ops.rs:28:26 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 + --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const X3: usize = -42 && -39; | ^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:38:19 - | -LL | const ARR3: [i32; X3] = [99; 6]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:41:18 + --> $DIR/const-integer-bool-ops.rs:37:18 | LL | const Y: usize = 42.0 == 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:44:19 - | -LL | const ARRR: [i32; Y] = [99; 1]; - | ^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:47:19 + --> $DIR/const-integer-bool-ops.rs:42:19 | LL | const Y1: usize = 42.0 >= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:50:20 - | -LL | const ARRR1: [i32; Y1] = [99; 1]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:53:19 + --> $DIR/const-integer-bool-ops.rs:47:19 | LL | const Y2: usize = 42.0 <= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:56:20 - | -LL | const ARRR2: [i32; Y2] = [99; 1]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:59:19 + --> $DIR/const-integer-bool-ops.rs:52:19 | LL | const Y3: usize = 42.0 > 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:62:20 - | -LL | const ARRR3: [i32; Y3] = [99; 0]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:65:19 + --> $DIR/const-integer-bool-ops.rs:57:19 | LL | const Y4: usize = 42.0 < 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:68:20 - | -LL | const ARRR4: [i32; Y4] = [99; 0]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:71:19 + --> $DIR/const-integer-bool-ops.rs:62:19 | LL | const Y5: usize = 42.0 != 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:74:20 - | -LL | const ARRR5: [i32; Y5] = [99; 0]; - | ^^ - error: aborting due to 18 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-len-underflow-separate-spans.rs b/tests/ui/consts/const-len-underflow-separate-spans.rs index 4544c8876ae09..b36257aafed18 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.rs +++ b/tests/ui/consts/const-len-underflow-separate-spans.rs @@ -9,5 +9,4 @@ const LEN: usize = ONE - TWO; fn main() { let a: [i8; LEN] = unimplemented!(); -//~^ constant } diff --git a/tests/ui/consts/const-len-underflow-separate-spans.stderr b/tests/ui/consts/const-len-underflow-separate-spans.stderr index 269553631cc67..b8dab871d741c 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.stderr +++ b/tests/ui/consts/const-len-underflow-separate-spans.stderr @@ -4,12 +4,6 @@ error[E0080]: evaluation of constant value failed LL | const LEN: usize = ONE - TWO; | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow -note: erroneous constant used - --> $DIR/const-len-underflow-separate-spans.rs:11:17 - | -LL | let a: [i8; LEN] = unimplemented!(); - | ^^^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/issue-39974.rs b/tests/ui/consts/issue-39974.rs index 503647ef4a82f..ff083865c6422 100644 --- a/tests/ui/consts/issue-39974.rs +++ b/tests/ui/consts/issue-39974.rs @@ -1,9 +1,9 @@ const LENGTH: f64 = 2; +//~^ ERROR: mismatched types struct Thing { f: [[f64; 2]; LENGTH], - //~^ ERROR mismatched types - //~| expected `usize`, found `f64` + //~^ ERROR: the constant `[const error]` is not of type `usize` } fn main() { diff --git a/tests/ui/consts/issue-39974.stderr b/tests/ui/consts/issue-39974.stderr index 56365e51e0a74..57be76397c361 100644 --- a/tests/ui/consts/issue-39974.stderr +++ b/tests/ui/consts/issue-39974.stderr @@ -1,9 +1,18 @@ error[E0308]: mismatched types - --> $DIR/issue-39974.rs:4:19 + --> $DIR/issue-39974.rs:1:21 + | +LL | const LENGTH: f64 = 2; + | ^ + | | + | expected `f64`, found integer + | help: use a float literal: `2.0` + +error: the constant `[const error]` is not of type `usize` + --> $DIR/issue-39974.rs:5:8 | LL | f: [[f64; 2]; LENGTH], - | ^^^^^^ expected `usize`, found `f64` + | ^^^^^^^^^^^^^^^^^^ expected `usize`, found `f64` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/issue-54954.rs b/tests/ui/consts/issue-54954.rs index 520bf508ff339..7bcfa05701995 100644 --- a/tests/ui/consts/issue-54954.rs +++ b/tests/ui/consts/issue-54954.rs @@ -9,8 +9,6 @@ trait Tt { } fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - //~^ constant - //~| constant z } diff --git a/tests/ui/consts/issue-54954.stderr b/tests/ui/consts/issue-54954.stderr index 85055828737b3..b0701bab793c5 100644 --- a/tests/ui/consts/issue-54954.stderr +++ b/tests/ui/consts/issue-54954.stderr @@ -16,18 +16,6 @@ LL | | core::mem::size_of::() LL | | } | |_____- `Tt::const_val` defined here -note: erroneous constant used - --> $DIR/issue-54954.rs:11:15 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ - -note: erroneous constant used - --> $DIR/issue-54954.rs:11:34 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ - error: aborting due to 2 previous errors Some errors have detailed explanations: E0379, E0790. diff --git a/tests/ui/consts/nested_erroneous_ctfe.rs b/tests/ui/consts/nested_erroneous_ctfe.rs index 1ec271401fb4c..3a726f6509413 100644 --- a/tests/ui/consts/nested_erroneous_ctfe.rs +++ b/tests/ui/consts/nested_erroneous_ctfe.rs @@ -1,4 +1,5 @@ fn main() { [9; || [9; []]]; //~^ ERROR: mismatched types + //~| ERROR: mismatched types } diff --git a/tests/ui/consts/nested_erroneous_ctfe.stderr b/tests/ui/consts/nested_erroneous_ctfe.stderr index b6a1725076bc6..6bfa6b41bf239 100644 --- a/tests/ui/consts/nested_erroneous_ctfe.stderr +++ b/tests/ui/consts/nested_erroneous_ctfe.stderr @@ -7,6 +7,19 @@ LL | [9; || [9; []]]; = note: expected type `usize` found array `[_; 0]` -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/nested_erroneous_ctfe.rs:2:9 + | +LL | [9; || [9; []]]; + | ^^^^^^^^^^ expected `usize`, found closure + | + = note: expected type `usize` + found closure `[closure@$DIR/nested_erroneous_ctfe.rs:2:9: 2:11]` +help: use parentheses to call this closure + | +LL | [9; (|| [9; []])()]; + | + +++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/refs_check_const_value_eq-issue-88876.rs b/tests/ui/consts/refs_check_const_value_eq-issue-88876.rs index 6ce9da4366800..5841d056b6552 100644 --- a/tests/ui/consts/refs_check_const_value_eq-issue-88876.rs +++ b/tests/ui/consts/refs_check_const_value_eq-issue-88876.rs @@ -1,5 +1,3 @@ -// check-pass - #![allow(incomplete_features)] #![feature(adt_const_params)] @@ -9,4 +7,5 @@ const FOO_ARR: &[&'static str; 2] = &["Hello", "Friend"]; fn main() { let _ = FooConst:: {}; + //~^ ERROR: the constant `&["Hello", "Friend"]` is not of type `&'static [&'static str]` } diff --git a/tests/ui/consts/refs_check_const_value_eq-issue-88876.stderr b/tests/ui/consts/refs_check_const_value_eq-issue-88876.stderr new file mode 100644 index 0000000000000..c496c67521f63 --- /dev/null +++ b/tests/ui/consts/refs_check_const_value_eq-issue-88876.stderr @@ -0,0 +1,14 @@ +error: the constant `&["Hello", "Friend"]` is not of type `&'static [&'static str]` + --> $DIR/refs_check_const_value_eq-issue-88876.rs:9:24 + | +LL | let _ = FooConst:: {}; + | ^^^^^^^ expected `&'static [&'static str]`, found `&'static [&'static str; 2]` + | +note: required by a bound in `FooConst` + --> $DIR/refs_check_const_value_eq-issue-88876.rs:4:17 + | +LL | struct FooConst {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `FooConst` + +error: aborting due to previous error + diff --git a/tests/ui/issues/issue-17252.stderr b/tests/ui/issues/issue-17252.stderr index aca5242b29689..8c7006ca93445 100644 --- a/tests/ui/issues/issue-17252.stderr +++ b/tests/ui/issues/issue-17252.stderr @@ -5,11 +5,11 @@ LL | const FOO: usize = FOO; | ^^^ | = note: ...which immediately requires const-evaluating + checking `FOO` again -note: cycle used when const-evaluating + checking `main::{constant#0}` - --> $DIR/issue-17252.rs:4:18 +note: cycle used when const-evaluating + checking `FOO` + --> $DIR/issue-17252.rs:1:1 | -LL | let _x: [u8; FOO]; // caused stack overflow prior to fix - | ^^^ +LL | const FOO: usize = FOO; + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/issues/issue-27008.rs b/tests/ui/issues/issue-27008.rs index adf8e779e0a04..110ecb877ece8 100644 --- a/tests/ui/issues/issue-27008.rs +++ b/tests/ui/issues/issue-27008.rs @@ -2,6 +2,5 @@ struct S; fn main() { let b = [0; S]; - //~^ ERROR mismatched types - //~| expected `usize`, found `S` + //~^ ERROR the constant `S` is not of type `usize` } diff --git a/tests/ui/issues/issue-27008.stderr b/tests/ui/issues/issue-27008.stderr index 9d18045aa794c..56db74838ab7c 100644 --- a/tests/ui/issues/issue-27008.stderr +++ b/tests/ui/issues/issue-27008.stderr @@ -1,9 +1,8 @@ -error[E0308]: mismatched types - --> $DIR/issue-27008.rs:4:17 +error: the constant `S` is not of type `usize` + --> $DIR/issue-27008.rs:4:13 | LL | let b = [0; S]; - | ^ expected `usize`, found `S` + | ^^^^^^ expected `usize`, found `S` error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-66706.rs b/tests/ui/issues/issue-66706.rs index 835fdfae86c03..4585bcc8cd57f 100644 --- a/tests/ui/issues/issue-66706.rs +++ b/tests/ui/issues/issue-66706.rs @@ -2,6 +2,7 @@ fn a() { [0; [|_: _ &_| ()].len()] //~^ ERROR expected `,`, found `&` //~| ERROR type annotations needed + //~| ERROR mismatched types } fn b() { @@ -12,11 +13,13 @@ fn b() { fn c() { [0; [|&_: _ &_| {}; 0 ].len()] //~^ ERROR expected `,`, found `&` + //~| ERROR mismatched types } fn d() { [0; match [|f @ &ref _| () ] {} ] //~^ ERROR expected identifier, found reserved identifier `_` + //~| ERROR mismatched types } fn main() {} diff --git a/tests/ui/issues/issue-66706.stderr b/tests/ui/issues/issue-66706.stderr index 8a30c0cad39c5..b4e243f18e70f 100644 --- a/tests/ui/issues/issue-66706.stderr +++ b/tests/ui/issues/issue-66706.stderr @@ -7,13 +7,13 @@ LL | [0; [|_: _ &_| ()].len()] | help: missing `,` error: expected identifier, found reserved identifier `_` - --> $DIR/issue-66706.rs:8:20 + --> $DIR/issue-66706.rs:9:20 | LL | [0; [|f @ &ref _| {} ; 0 ].len() ]; | ^ expected identifier, found reserved identifier error: expected `,`, found `&` - --> $DIR/issue-66706.rs:13:17 + --> $DIR/issue-66706.rs:14:17 | LL | [0; [|&_: _ &_| {}; 0 ].len()] | -^ expected `,` @@ -21,7 +21,7 @@ LL | [0; [|&_: _ &_| {}; 0 ].len()] | help: missing `,` error: expected identifier, found reserved identifier `_` - --> $DIR/issue-66706.rs:18:26 + --> $DIR/issue-66706.rs:20:26 | LL | [0; match [|f @ &ref _| () ] {} ] | ^ expected identifier, found reserved identifier @@ -32,6 +32,31 @@ error[E0282]: type annotations needed LL | [0; [|_: _ &_| ()].len()] | ^ cannot infer type -error: aborting due to 5 previous errors +error[E0308]: mismatched types + --> $DIR/issue-66706.rs:2:5 + | +LL | fn a() { + | - help: try adding a return type: `-> [i32; [|_: _ &_| ()].len()]` +LL | [0; [|_: _ &_| ()].len()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `[{integer}; [|_: _ &_| ()].len()]` + +error[E0308]: mismatched types + --> $DIR/issue-66706.rs:14:5 + | +LL | fn c() { + | - help: try adding a return type: `-> [i32; [|&_: _ &_| {}; 0 ].len()]` +LL | [0; [|&_: _ &_| {}; 0 ].len()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `[{integer}; [|&_: _ &_| {}; 0 ].len()]` + +error[E0308]: mismatched types + --> $DIR/issue-66706.rs:20:5 + | +LL | fn d() { + | - help: try adding a return type: `-> [i32; match [|f @ &ref _| () ] {}]` +LL | [0; match [|f @ &ref _| () ] {} ] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `[{integer}; match [|f @ &ref _| () ] {}]` + +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/resolve/issue-50599.rs b/tests/ui/resolve/issue-50599.rs index 72238a59198a7..00588735b9a59 100644 --- a/tests/ui/resolve/issue-50599.rs +++ b/tests/ui/resolve/issue-50599.rs @@ -2,5 +2,4 @@ fn main() { const N: u32 = 1_000; const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value let mut digits = [0u32; M]; - //~^ constant } diff --git a/tests/ui/resolve/issue-50599.stderr b/tests/ui/resolve/issue-50599.stderr index d7419b64facd2..d58b6ca5b5c42 100644 --- a/tests/ui/resolve/issue-50599.stderr +++ b/tests/ui/resolve/issue-50599.stderr @@ -16,12 +16,6 @@ LL - const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; LL + const M: usize = (f64::from(N) * LOG10_2) as usize; | -note: erroneous constant used - --> $DIR/issue-50599.rs:4:29 - | -LL | let mut digits = [0u32; M]; - | ^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/stats/hir-stats.rs b/tests/ui/stats/hir-stats.rs index 9bb87026b6418..8bd4d1fbf28f4 100644 --- a/tests/ui/stats/hir-stats.rs +++ b/tests/ui/stats/hir-stats.rs @@ -1,6 +1,7 @@ // check-pass // compile-flags: -Zhir-stats // only-x86_64 +// ignore-stage1 // Type layouts sometimes change. When that happens, until the next bootstrap // bump occurs, stage1 and stage2 will give different outputs for this test. diff --git a/tests/ui/symbol-names/const-generics-structural-demangling.rs b/tests/ui/symbol-names/const-generics-structural-demangling.rs index df09ba494a74f..98609f69aa142 100644 --- a/tests/ui/symbol-names/const-generics-structural-demangling.rs +++ b/tests/ui/symbol-names/const-generics-structural-demangling.rs @@ -51,7 +51,7 @@ pub struct OptionUsize>; //~^ ERROR symbol-name //~| ERROR demangling //~| ERROR demangling-alt(::None}>>) -impl OptionUsize<{None}> {} +impl OptionUsize<{None::<_>}> {} // HACK(eddyb) the full mangling is only in `.stderr` because we can normalize // the `core` disambiguator hash away there, but not here. diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs index 91c6dfb8e0a92..a788b130206d0 100644 --- a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs +++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs @@ -1,10 +1,17 @@ -#![feature(non_lifetime_binders)] +#![feature(non_lifetime_binders, generic_const_exprs)] //~^ WARN the feature `non_lifetime_binders` is incomplete +//~| WARN the feature `generic_const_exprs` is incomplete + +fn a() +where + for [(); C + 1]: Copy, + //~^ ERROR cannot capture late-bound const parameter in a constant +{ +} fn b() where for [(); C]: Copy, - //~^ ERROR cannot capture late-bound const parameter in a constant { } diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr index 69bb605bf41ca..768ad1b0fc2d3 100644 --- a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr +++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr @@ -1,19 +1,27 @@ warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/capture-late-ct-in-anon.rs:1:12 | -LL | #![feature(non_lifetime_binders)] +LL | #![feature(non_lifetime_binders, generic_const_exprs)] | ^^^^^^^^^^^^^^^^^^^^ | = note: see issue #108185 for more information = note: `#[warn(incomplete_features)]` on by default +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/capture-late-ct-in-anon.rs:1:34 + | +LL | #![feature(non_lifetime_binders, generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + error: cannot capture late-bound const parameter in a constant - --> $DIR/capture-late-ct-in-anon.rs:6:30 + --> $DIR/capture-late-ct-in-anon.rs:7:30 | -LL | for [(); C]: Copy, +LL | for [(); C + 1]: Copy, | -------------- ^ | | | parameter defined here -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error; 2 warnings emitted diff --git a/tests/ui/type/type-dependent-def-issue-49241.rs b/tests/ui/type/type-dependent-def-issue-49241.rs index caf5bade5c75b..4b6bc6124dbf3 100644 --- a/tests/ui/type/type-dependent-def-issue-49241.rs +++ b/tests/ui/type/type-dependent-def-issue-49241.rs @@ -2,5 +2,4 @@ fn main() { let v = vec![0]; const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant let s: [u32; l] = v.into_iter().collect(); - //~^ constant } diff --git a/tests/ui/type/type-dependent-def-issue-49241.stderr b/tests/ui/type/type-dependent-def-issue-49241.stderr index af16a6e8f8418..64c7687f7a882 100644 --- a/tests/ui/type/type-dependent-def-issue-49241.stderr +++ b/tests/ui/type/type-dependent-def-issue-49241.stderr @@ -6,12 +6,6 @@ LL | const l: usize = v.count(); | | | help: consider using `let` instead of `const`: `let l` -note: erroneous constant used - --> $DIR/type-dependent-def-issue-49241.rs:4:18 - | -LL | let s: [u32; l] = v.into_iter().collect(); - | ^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0435`.