diff --git a/.mailmap b/.mailmap index fdb62a9d7782..874a42656c51 100644 --- a/.mailmap +++ b/.mailmap @@ -254,6 +254,7 @@ Jack Huey Jacob Jacob Greenfield Jacob Pratt +Jacob Pratt Jake Vossen Jakob Degen Jakob Lautrup Nysom diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 3032042ff9fe..84e648f4923e 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -116,7 +116,7 @@ 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_to_const_arg(count); 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 65e387de800c..c3ff7b4b8972 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -235,8 +235,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_anon_const(&mut self, constant: &'hir AnonConst) { - // FIXME: use real span? - self.insert(DUMMY_SP, constant.hir_id, Node::AnonConst(constant)); + self.insert(constant.span, constant.hir_id, Node::AnonConst(constant)); self.with_parent(constant.hir_id, |this| { intravisit::walk_anon_const(this, constant); @@ -252,8 +251,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir>) { - // FIXME: use real span? - self.insert(DUMMY_SP, const_arg.hir_id, Node::ConstArg(const_arg)); + self.insert(const_arg.span(), const_arg.hir_id, Node::ConstArg(const_arg)); self.with_parent(const_arg.hir_id, |this| { intravisit::walk_const_arg(this, const_arg); @@ -387,13 +385,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { }); } - fn visit_array_length(&mut self, len: &'hir ArrayLen<'hir>) { - match len { - ArrayLen::Infer(inf) => self.insert(inf.span, inf.hir_id, Node::ArrayLenInfer(inf)), - ArrayLen::Body(..) => intravisit::walk_array_len(self, len), - } - } - fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) { self.visit_pat(p) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 96546239f4c2..7ffe4db6e45e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1257,9 +1257,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }), )) } - TyKind::Array(ty, length) => { - hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length)) - } + TyKind::Array(ty, length) => hir::TyKind::Array( + self.lower_ty(ty, itctx), + self.lower_array_length_to_const_arg(length), + ), TyKind::Typeof(expr) => hir::TyKind::Typeof(self.lower_anon_const_to_anon_const(expr)), TyKind::TraitObject(bounds, kind) => { let mut lifetime_bound = None; @@ -2007,14 +2008,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.expr_block(block) } - fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen<'hir> { + fn lower_array_length_to_const_arg(&mut self, c: &AnonConst) -> &'hir hir::ConstArg<'hir> { match c.value.kind { ExprKind::Underscore => { if self.tcx.features().generic_arg_infer() { - hir::ArrayLen::Infer(hir::InferArg { - hir_id: self.lower_node_id(c.id), - span: self.lower_span(c.value.span), - }) + let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span)); + self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind }) } else { feature_err( &self.tcx.sess, @@ -2023,10 +2022,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fluent_generated::ast_lowering_underscore_array_length_unstable, ) .stash(c.value.span, StashKey::UnderscoreForArrayLengths); - hir::ArrayLen::Body(self.lower_anon_const_to_const_arg(c)) + self.lower_anon_const_to_const_arg(c) } } - _ => hir::ArrayLen::Body(self.lower_anon_const_to_const_arg(c)), + _ => self.lower_anon_const_to_const_arg(c), } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 12dec75e65cf..97aa88c1de8d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -275,6 +275,7 @@ impl<'hir> ConstArg<'hir> { match self.kind { ConstArgKind::Path(path) => path.span(), ConstArgKind::Anon(anon) => anon.span, + ConstArgKind::Infer(span) => span, } } } @@ -289,6 +290,11 @@ pub enum ConstArgKind<'hir> { /// However, in the future, we'll be using it for all of those. Path(QPath<'hir>), Anon(&'hir AnonConst), + /// **Note:** Not all inferred consts are represented as + /// `ConstArgKind::Infer`. In cases where it is ambiguous whether + /// a generic arg is a type or a const, inference variables are + /// represented as `GenericArg::Infer` instead. + Infer(Span), } #[derive(Clone, Copy, Debug, HashStable_Generic)] @@ -308,6 +314,10 @@ pub enum GenericArg<'hir> { Lifetime(&'hir Lifetime), Type(&'hir Ty<'hir>), Const(&'hir ConstArg<'hir>), + /// **Note:** Inference variables are only represented as + /// `GenericArg::Infer` in cases where it is ambiguous whether + /// a generic arg is a type or a const. Otherwise, inference variables + /// are represented as `TyKind::Infer` or `ConstArgKind::Infer`. Infer(InferArg), } @@ -1645,29 +1655,6 @@ impl fmt::Display for ConstContext { /// A literal. pub type Lit = Spanned; -#[derive(Copy, Clone, Debug, HashStable_Generic)] -pub enum ArrayLen<'hir> { - Infer(InferArg), - Body(&'hir ConstArg<'hir>), -} - -impl ArrayLen<'_> { - pub fn span(self) -> Span { - match self { - ArrayLen::Infer(arg) => arg.span, - ArrayLen::Body(body) => body.span(), - } - } - - pub fn hir_id(self) -> HirId { - match self { - ArrayLen::Infer(InferArg { hir_id, .. }) | ArrayLen::Body(&ConstArg { 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) @@ -2115,7 +2102,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<'hir>), + Repeat(&'hir Expr<'hir>, &'hir ConstArg<'hir>), /// A suspension point for coroutines (i.e., `yield `). Yield(&'hir Expr<'hir>, YieldSource), @@ -2625,7 +2612,7 @@ impl<'hir> Ty<'hir> { TyKind::Infer => true, TyKind::Slice(ty) => ty.is_suggestable_infer_ty(), TyKind::Array(ty, length) => { - ty.is_suggestable_infer_ty() || matches!(length, ArrayLen::Infer(..)) + ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..)) } TyKind::Tup(tys) => tys.iter().any(Self::is_suggestable_infer_ty), TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => mut_ty.ty.is_suggestable_infer_ty(), @@ -2834,7 +2821,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<'hir>), + 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`). @@ -2861,6 +2848,11 @@ pub enum TyKind<'hir> { Typeof(&'hir AnonConst), /// `TyKind::Infer` means the type should be inferred instead of it having been /// specified. This can appear anywhere in a type. + /// + /// **Note:** Not all inferred types are represented as + /// `TyKind::Infer`. In cases where it is ambiguous whether + /// a generic arg is a type or a const, inference variables are + /// represented as `GenericArg::Infer` instead. Infer, /// Placeholder for a type that has failed to be defined. Err(rustc_span::ErrorGuaranteed), @@ -3801,8 +3793,6 @@ pub enum Node<'hir> { Crate(&'hir Mod<'hir>), Infer(&'hir InferArg), WherePredicate(&'hir WherePredicate<'hir>), - // FIXME: Merge into `Node::Infer`. - ArrayLenInfer(&'hir InferArg), PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg), // Created by query feeding Synthetic, @@ -3856,7 +3846,6 @@ impl<'hir> Node<'hir> { | Node::OpaqueTy(..) | Node::Infer(..) | Node::WherePredicate(..) - | Node::ArrayLenInfer(..) | Node::Synthetic | Node::Err(..) => None, } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index faaea41047fc..602aa8be740a 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -343,9 +343,6 @@ pub trait Visitor<'v>: Sized { fn visit_pat_field(&mut self, f: &'v PatField<'v>) -> Self::Result { walk_pat_field(self, f) } - fn visit_array_length(&mut self, len: &'v ArrayLen<'v>) -> Self::Result { - walk_array_len(self, len) - } fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result { walk_anon_const(self, c) } @@ -710,14 +707,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<'v>) -> V::Result { - match len { - // FIXME: Use `visit_infer` here. - ArrayLen::Infer(InferArg { hir_id, span: _ }) => visitor.visit_id(*hir_id), - ArrayLen::Body(c) => visitor.visit_const_arg(c), - } -} - pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) -> V::Result { try_visit!(visitor.visit_id(constant.hir_id)); visitor.visit_nested_body(constant.body) @@ -739,6 +728,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( match &const_arg.kind { ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, const_arg.hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), + ConstArgKind::Infer(..) => V::Result::output(), } } @@ -753,7 +743,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) } ExprKind::Repeat(ref element, ref count) => { try_visit!(visitor.visit_expr(element)); - try_visit!(visitor.visit_array_length(count)); + try_visit!(visitor.visit_const_arg(count)); } ExprKind::Struct(ref qpath, fields, ref optional_base) => { try_visit!(visitor.visit_qpath(qpath, expression.hir_id, expression.span)); @@ -901,7 +891,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul } TyKind::Array(ref ty, ref length) => { try_visit!(visitor.visit_ty(ty)); - try_visit!(visitor.visit_array_length(length)); + try_visit!(visitor.visit_const_arg(length)); } TyKind::TraitObject(bounds, ref lifetime, _syntax) => { for bound in bounds { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index cf062e82cb60..8d5824130d85 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -151,11 +151,11 @@ impl<'v> Visitor<'v> for HirPlaceholderCollector { _ => {} } } - fn visit_array_length(&mut self, length: &'v hir::ArrayLen<'v>) { - if let hir::ArrayLen::Infer(inf) = length { - self.0.push(inf.span); + fn visit_const_arg(&mut self, const_arg: &'v hir::ConstArg<'v>) { + if let hir::ConstArgKind::Infer(span) = const_arg.kind { + self.0.push(span); } - intravisit::walk_array_len(self, length) + intravisit::walk_const_arg(self, const_arg) } } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index c31bff28fd34..077696ac1f24 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -181,7 +181,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // expressions' count (i.e. `N` in `[x; N]`), and explicit // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`), // as they shouldn't be able to cause query cycle errors. - Node::Expr(Expr { kind: ExprKind::Repeat(_, ArrayLen::Body(ct)), .. }) + Node::Expr(Expr { kind: ExprKind::Repeat(_, ct), .. }) if ct.anon_const_hir_id() == Some(hir_id) => { Some(parent_did) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 18fb5bfd912f..7cf99bebd36a 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -145,7 +145,7 @@ fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span // Easy case: arrays repeat expressions. Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. }) | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) - if constant.hir_id() == arg_hir_id => + if constant.hir_id == arg_hir_id => { return tcx.types.usize; } @@ -579,8 +579,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ x => bug!("unexpected non-type Node::GenericParam: {:?}", x), }, - Node::ArrayLenInfer(_) => tcx.types.usize, - x => { bug!("unexpected sort of node in type_of(): {:?}", x); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index ae1279d428c1..c3f4fc8699a3 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -104,7 +104,7 @@ fn generic_arg_mismatch_err( GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }), GenericParamDefKind::Const { .. }, ) if tcx.type_of(param.def_id).skip_binder() == tcx.types.usize => { - let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id())); + let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id)); if let Ok(snippet) = snippet { err.span_suggestion( arg.span(), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index cf780a3d3bba..7b8e95f3434e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2090,6 +2090,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { format!("Const::lower_const_arg: invalid qpath {qpath:?}"), ), hir::ConstArgKind::Anon(anon) => Const::from_anon_const(tcx, anon.def_id), + hir::ConstArgKind::Infer(span) => self.ct_infer(None, span), } } @@ -2310,13 +2311,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { tcx.at(span).type_of(def_id).instantiate(tcx, args) } hir::TyKind::Array(ty, length) => { - let length = match length { - hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span), - hir::ArrayLen::Body(constant) => { - self.lower_const_arg(constant, FeedConstTy::No) - } - }; - + let length = self.lower_const_arg(length, FeedConstTy::No); Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length) } hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(), diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 5a5b39c694f8..11864b61a94e 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -118,7 +118,6 @@ impl<'a> State<'a> { Node::LetStmt(a) => self.print_local_decl(a), Node::Crate(..) => panic!("cannot print Crate"), Node::WherePredicate(pred) => self.print_where_predicate(pred), - Node::ArrayLenInfer(_) => self.word("_"), Node::Synthetic => unreachable!(), Node::Err(_) => self.word("/*ERROR*/"), } @@ -315,7 +314,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) => { @@ -986,13 +985,6 @@ impl<'a> State<'a> { self.print_else(elseopt) } - fn print_array_length(&mut self, len: &hir::ArrayLen<'_>) { - match len { - hir::ArrayLen::Infer(..) => self.word("_"), - hir::ArrayLen::Body(ct) => self.print_const_arg(ct), - } - } - fn print_anon_const(&mut self, constant: &hir::AnonConst) { self.ann.nested(self, Nested::Body(constant.body)) } @@ -1001,6 +993,7 @@ impl<'a> State<'a> { match &const_arg.kind { ConstArgKind::Path(qpath) => self.print_qpath(qpath, true), ConstArgKind::Anon(anon) => self.print_anon_const(anon), + ConstArgKind::Infer(..) => self.word("_"), } } @@ -1073,12 +1066,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() } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index b4715839cf56..4699b342cec2 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -19,7 +19,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, HirId, QPath}; -use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _; +use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _}; use rustc_infer::infer; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_infer::traits::ObligationCause; @@ -425,7 +425,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | hir::Node::Crate(_) | hir::Node::Infer(_) | hir::Node::WherePredicate(_) - | hir::Node::ArrayLenInfer(_) | hir::Node::PreciseCapturingNonLifetimeArg(_) | hir::Node::OpaqueTy(_) => { unreachable!("no sub-expr expected for {parent_node:?}") @@ -1673,9 +1672,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { else { return; }; - if let hir::TyKind::Array(_, length) = ty.peel_refs().kind - && let hir::ArrayLen::Body(ct) = length - { + if let hir::TyKind::Array(_, ct) = ty.peel_refs().kind { let span = ct.span(); self.dcx().try_steal_modify_and_emit_err( span, @@ -1713,13 +1710,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_expr_repeat( &self, element: &'tcx hir::Expr<'tcx>, - count: &'tcx hir::ArrayLen<'tcx>, + count: &'tcx hir::ConstArg<'tcx>, expected: Expectation<'tcx>, expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; let count_span = count.span(); - let count = self.try_structurally_resolve_const(count_span, self.lower_array_length(count)); + let count = self.try_structurally_resolve_const( + count_span, + self.normalize(count_span, self.lower_const_arg(count, FeedConstTy::No)), + ); if let Some(count) = count.try_to_target_usize(tcx) { 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 76bbcfd1312d..863be3bdcb29 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -487,24 +487,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(crate) fn lower_array_length(&self, length: &hir::ArrayLen<'tcx>) -> ty::Const<'tcx> { - match length { - hir::ArrayLen::Infer(inf) => self.ct_infer(None, inf.span), - hir::ArrayLen::Body(const_arg) => { - let span = const_arg.span(); - let c = self.lowerer().lower_const_arg(const_arg, FeedConstTy::No); - self.register_wf_obligation(c.into(), span, ObligationCauseCode::WellFormed(None)); - self.normalize(span, c) - } - } - } - pub(crate) fn lower_const_arg( &self, const_arg: &'tcx hir::ConstArg<'tcx>, - param_def_id: DefId, + feed: FeedConstTy, ) -> ty::Const<'tcx> { - let ct = self.lowerer().lower_const_arg(const_arg, FeedConstTy::Param(param_def_id)); + let ct = self.lowerer().lower_const_arg(const_arg, feed); self.register_wf_obligation( ct.into(), self.tcx.hir().span(const_arg.hir_id), @@ -1279,7 +1267,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.lower_ty(ty).raw.into() } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { - self.fcx.lower_const_arg(ct, param.def_id).into() + self.fcx.lower_const_arg(ct, FeedConstTy::Param(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 3754fd024282..b31ee1a55d63 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -7,7 +7,7 @@ use rustc_hir_analysis::hir_ty_lowering::generics::{ check_generic_arg_count_for_call, lower_generic_args, }; use rustc_hir_analysis::hir_ty_lowering::{ - GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason, + FeedConstTy, GenericArgsLowerer, HirTyLowerer, IsMethodCall, RegionInferReason, }; use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk}; use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext}; @@ -429,7 +429,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self.cfcx.lower_ty(ty).raw.into() } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { - self.cfcx.lower_const_arg(ct, param.def_id).into() + self.cfcx.lower_const_arg(ct, FeedConstTy::Param(param.def_id)).into() } (GenericParamDefKind::Type { .. }, GenericArg::Infer(inf)) => { self.cfcx.ty_infer(Some(param), inf.span).into() diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 4900575c36e3..0c701c834f27 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -948,7 +948,6 @@ impl<'hir> Map<'hir> { Node::LetStmt(local) => local.span, Node::Crate(item) => item.spans.inner_span, Node::WherePredicate(pred) => pred.span, - Node::ArrayLenInfer(inf) => inf.span, Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span, Node::Synthetic => unreachable!(), Node::Err(span) => span, @@ -1226,7 +1225,6 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { } Node::Crate(..) => String::from("(root_crate)"), Node::WherePredicate(_) => node_str("where predicate"), - Node::ArrayLenInfer(_) => node_str("array len infer"), Node::Synthetic => unreachable!(), Node::Err(_) => node_str("error"), Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 0f9d4cb1982d..8ba7969207e8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1837,11 +1837,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; if let Some(tykind) = tykind && let hir::TyKind::Array(_, length) = tykind - && let hir::ArrayLen::Body(ct) = length && let Some((scalar, ty)) = sz.found.try_to_scalar() && ty == self.tcx.types.usize { - let span = ct.span(); + let span = length.span(); Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { span, length: scalar.to_target_usize(&self.tcx).unwrap(), diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 0bc65cdbc55a..5d3997e14e3e 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -486,7 +486,6 @@ impl BinaryHeap { /// heap.push(4); /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_binary_heap_new_in", issue = "125961")] #[must_use] pub const fn new_in(alloc: A) -> BinaryHeap { BinaryHeap { data: Vec::new_in(alloc) } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 108224b27fa8..84f4202c02a9 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -91,8 +91,6 @@ // // Library features: // tidy-alphabetical-start -#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))] -#![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))] #![cfg_attr(test, feature(str_as_str))] #![feature(alloc_layout_extra)] #![feature(allocator_api)] @@ -107,13 +105,8 @@ #![feature(box_uninit_write)] #![feature(clone_to_uninit)] #![feature(coerce_unsized)] -#![feature(const_align_of_val)] -#![feature(const_box)] #![feature(const_eval_select)] #![feature(const_heap)] -#![feature(const_maybe_uninit_write)] -#![feature(const_size_of_val)] -#![feature(const_vec_string_slice)] #![feature(core_intrinsics)] #![feature(deprecated_suggestion)] #![feature(deref_pure_trait)] @@ -170,7 +163,6 @@ #![feature(allow_internal_unstable)] #![feature(cfg_sanitize)] #![feature(const_precise_live_drops)] -#![feature(const_try)] #![feature(decl_macro)] #![feature(dropck_eyepatch)] #![feature(fundamental)] diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 02bbb40ef81d..bcab17e7b2dd 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -4,8 +4,6 @@ #![feature(assert_matches)] #![feature(btree_extract_if)] #![feature(cow_is_borrowed)] -#![feature(const_heap)] -#![feature(const_try)] #![feature(core_intrinsics)] #![feature(extract_if)] #![feature(exact_size_is_empty)] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index c55397903277..cfa4c1fb5647 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -713,7 +713,6 @@ impl Cell<[T; N]> { /// let array_cell: &[Cell; 3] = cell_array.as_array_of_cells(); /// ``` #[unstable(feature = "as_array_of_cells", issue = "88248")] - #[rustc_const_unstable(feature = "as_array_of_cells", issue = "88248")] pub const fn as_array_of_cells(&self) -> &[Cell; N] { // SAFETY: `Cell` has the same memory layout as `T`. unsafe { &*(self as *const Cell<[T; N]> as *const [Cell; N]) } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 1b9a9ea3ecff..ab9c33ee7547 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -109,23 +109,7 @@ // tidy-alphabetical-start #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] -#![feature(const_align_of_val)] -#![feature(const_align_of_val_raw)] -#![feature(const_alloc_layout)] -#![feature(const_black_box)] -#![feature(const_eq_ignore_ascii_case)] #![feature(const_eval_select)] -#![feature(const_heap)] -#![feature(const_nonnull_new)] -#![feature(const_ptr_sub_ptr)] -#![feature(const_raw_ptr_comparison)] -#![feature(const_size_of_val)] -#![feature(const_size_of_val_raw)] -#![feature(const_sockaddr_setters)] -#![feature(const_swap)] -#![feature(const_try)] -#![feature(const_type_id)] -#![feature(const_type_name)] #![feature(const_typed_swap)] #![feature(core_intrinsics)] #![feature(coverage_attribute)] @@ -165,10 +149,7 @@ #![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic_equal_alignment)] #![feature(cfg_ub_checks)] -#![feature(const_for)] -#![feature(const_is_char_boundary)] #![feature(const_precise_live_drops)] -#![feature(const_str_split_at)] #![feature(const_trait_impl)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 10aca6e99801..e97af081143b 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -614,7 +614,6 @@ macro_rules! nonzero_integer { /// ``` /// #[unstable(feature = "non_zero_count_ones", issue = "120287")] - #[rustc_const_unstable(feature = "non_zero_count_ones", issue = "120287")] #[doc(alias = "popcount")] #[doc(alias = "popcnt")] #[must_use = "this returns the result of the operation, \ diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 0ebd765b5490..c853db181cee 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3162,7 +3162,6 @@ macro_rules! uint_impl { #[inline] #[unstable(feature = "wrapping_next_power_of_two", issue = "32463", reason = "needs decision on wrapping behavior")] - #[rustc_const_unstable(feature = "wrapping_next_power_of_two", issue = "32463")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn wrapping_next_power_of_two(self) -> Self { diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 6f6815f49cd2..f100adecbbb7 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -346,7 +346,6 @@ impl *const T { /// ``` #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> where T: Sized, @@ -1528,7 +1527,6 @@ impl *const [T] { /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. #[unstable(feature = "slice_as_array", issue = "133508")] - #[rustc_const_unstable(feature = "slice_as_array", issue = "133508")] #[inline] #[must_use] pub const fn as_array(self) -> Option<*const [T; N]> { @@ -1608,7 +1606,6 @@ impl *const [T] { /// [allocated object]: crate::ptr#allocated-object #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { if self.is_null() { None diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index b6fc0caebd02..bc4c4e168a36 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -2111,7 +2111,6 @@ pub fn addr_eq(p: *const T, q: *const U) -> bool { /// when compiled with optimization: /// /// ``` -/// # #![feature(ptr_fn_addr_eq)] /// let f: fn(i32) -> i32 = |x| x; /// let g: fn(i32) -> i32 = |x| x + 0; // different closure, different body /// let h: fn(u32) -> u32 = |x| x + 0; // different signature too @@ -2136,7 +2135,6 @@ pub fn addr_eq(p: *const T, q: *const U) -> bool { /// # Examples /// /// ``` -/// #![feature(ptr_fn_addr_eq)] /// use std::ptr; /// /// fn a() { println!("a"); } @@ -2145,7 +2143,7 @@ pub fn addr_eq(p: *const T, q: *const U) -> bool { /// ``` /// /// [subtype]: https://doc.rust-lang.org/reference/subtyping.html -#[unstable(feature = "ptr_fn_addr_eq", issue = "129322")] +#[stable(feature = "ptr_fn_addr_eq", since = "CURRENT_RUSTC_VERSION")] #[inline(always)] #[must_use = "function pointer comparison produces a value"] pub fn fn_addr_eq(f: T, g: U) -> bool { diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 678c6029158b..6d0361b8c63f 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -342,7 +342,6 @@ impl *mut T { /// ``` #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit> where T: Sized, @@ -676,7 +675,6 @@ impl *mut T { /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion). #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_mut<'a>(self) -> Option<&'a mut MaybeUninit> where T: Sized, @@ -1762,7 +1760,6 @@ impl *mut [T] { /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. #[unstable(feature = "slice_as_array", issue = "133508")] - #[rustc_const_unstable(feature = "slice_as_array", issue = "133508")] #[inline] #[must_use] pub const fn as_mut_array(self) -> Option<*mut [T; N]> { @@ -1963,7 +1960,6 @@ impl *mut [T] { /// [allocated object]: crate::ptr#allocated-object #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit]> { if self.is_null() { None @@ -2015,7 +2011,6 @@ impl *mut [T] { /// [allocated object]: crate::ptr#allocated-object #[inline] #[unstable(feature = "ptr_as_uninit", issue = "75402")] - #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")] pub const unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit]> { if self.is_null() { None diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index a796820a7e46..ebdc918a729c 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -92,6 +92,7 @@ impl Unique { /// Creates a new `Unique` if `ptr` is non-null. #[inline] + // rustc_const_unstable attribute can be removed when `const_nonnull_new` is stable #[rustc_const_unstable(feature = "ptr_internals", issue = "none")] pub const fn new(ptr: *mut T) -> Option { if let Some(pointer) = NonNull::new(ptr) { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index bc49b7d97972..a5507f0f3381 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -860,7 +860,6 @@ impl [T] { /// /// If `N` is not exactly equal to slice's the length of `self`, then this method returns `None`. #[unstable(feature = "slice_as_array", issue = "133508")] - #[rustc_const_unstable(feature = "slice_as_array", issue = "133508")] #[inline] #[must_use] pub const fn as_array(&self) -> Option<&[T; N]> { @@ -879,7 +878,6 @@ impl [T] { /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. #[unstable(feature = "slice_as_array", issue = "133508")] - #[rustc_const_unstable(feature = "slice_as_array", issue = "133508")] #[inline] #[must_use] pub const fn as_mut_array(&mut self) -> Option<&mut [T; N]> { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 4fbf47e20039..ec4b42b966b3 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -16,7 +16,6 @@ #![feature(const_align_of_val_raw)] #![feature(const_black_box)] #![feature(const_eval_select)] -#![feature(const_heap)] #![feature(const_nonnull_new)] #![feature(const_swap)] #![feature(const_trait_impl)] diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 15770248b310..4aa47ce4e4f5 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -22,7 +22,6 @@ // This library is copied into rust-analyzer to allow loading rustc compiled proc macros. // Please avoid unstable features where possible to minimize the amount of changes necessary // to make it compile with rust-analyzer on stable. -#![feature(rustc_allow_const_fn_unstable)] #![feature(staged_api)] #![feature(allow_internal_unstable)] #![feature(decl_macro)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 059c8d8309c8..143878170f08 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -409,9 +409,7 @@ // // Only for const-ness: // tidy-alphabetical-start -#![feature(const_collections_with_hasher)] #![feature(io_const_error)] -#![feature(thread_local_internals)] // tidy-alphabetical-end // #![default_lib_allocator] diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 093f216accbe..5b407ea9a2b4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -290,6 +290,7 @@ pub(crate) fn clean_const<'tcx>( ConstantKind::Path { path: qpath_to_string(qpath).into() } } hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, + hir::ConstArgKind::Infer(..) => ConstantKind::Infer, } } @@ -1803,30 +1804,27 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))), TyKind::Pat(ty, pat) => Type::Pat(Box::new(clean_ty(ty, cx)), format!("{pat:?}").into()), - TyKind::Array(ty, ref length) => { - let length = match length { - hir::ArrayLen::Infer(..) => "_".to_string(), - hir::ArrayLen::Body(const_arg) => { - // NOTE(min_const_generics): We can't use `const_eval_poly` for constants - // as we currently do not supply the parent generics to anonymous constants - // but do allow `ConstKind::Param`. - // - // `const_eval_poly` tries to first substitute generic parameters which - // results in an ICE while manually constructing the constant and using `eval` - // does nothing for `ConstKind::Param`. + TyKind::Array(ty, ref const_arg) => { + // NOTE(min_const_generics): We can't use `const_eval_poly` for constants + // as we currently do not supply the parent generics to anonymous constants + // but do allow `ConstKind::Param`. + // + // `const_eval_poly` tries to first substitute generic parameters which + // results in an ICE while manually constructing the constant and using `eval` + // does nothing for `ConstKind::Param`. + let length = match const_arg.kind { + hir::ConstArgKind::Infer(..) => "_".to_string(), + hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) => { + let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); + let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id); + let ct = cx.tcx.normalize_erasing_regions(typing_env, ct); + print_const(cx, ct) + } + hir::ConstArgKind::Path(..) => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, FeedConstTy::No); - let ct = if let hir::ConstArgKind::Anon(hir::AnonConst { def_id, .. }) = - const_arg.kind - { - let typing_env = ty::TypingEnv::post_analysis(cx.tcx, *def_id); - cx.tcx.normalize_erasing_regions(typing_env, ct) - } else { - ct - }; print_const(cx, ct) } }; - Array(Box::new(clean_ty(ty, cx)), length.into()) } TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()), diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 01d2661f73ed..715bf68374a5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2399,6 +2399,8 @@ pub(crate) enum ConstantKind { Extern { def_id: DefId }, /// `const FOO: u32 = ...;` Local { def_id: DefId, body: BodyId }, + /// An inferred constant as in `[10u8; _]`. + Infer, } impl Constant { @@ -2424,6 +2426,7 @@ impl ConstantKind { ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { rendered_const(tcx, tcx.hir().body(body), tcx.hir().body_owner_def_id(body)) } + ConstantKind::Infer { .. } => "_".to_string(), } } @@ -2431,7 +2434,8 @@ impl ConstantKind { match *self { ConstantKind::TyConst { .. } | ConstantKind::Path { .. } - | ConstantKind::Anonymous { .. } => None, + | ConstantKind::Anonymous { .. } + | ConstantKind::Infer => None, ConstantKind::Extern { def_id } | ConstantKind::Local { def_id, .. } => { print_evaluated_const(tcx, def_id, true, true) } @@ -2442,7 +2446,8 @@ impl ConstantKind { match *self { ConstantKind::TyConst { .. } | ConstantKind::Extern { .. } - | ConstantKind::Path { .. } => false, + | ConstantKind::Path { .. } + | ConstantKind::Infer => false, ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { is_literal_expr(tcx, body.hir_id) } diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index 4ef881f11d59..46d7df6995a9 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -5,7 +5,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_from_proc_macro; use clippy_utils::macros::macro_backtrace; use clippy_utils::source::snippet; -use rustc_hir::{ArrayLen, Expr, ExprKind, Item, ItemKind, Node}; +use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ConstKind}; @@ -118,13 +118,13 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { /// Only giving help messages if the expr does not contains macro expanded codes. fn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool { - /// Check if the span of `ArrayLen` of a repeat expression is within the expr's span, + /// Check if the span of `ConstArg` of a repeat expression is within the expr's span, /// if not, meaning this repeat expr is definitely from some proc-macro. /// /// This is a fail-safe to a case where even the `is_from_proc_macro` is unable to determain the /// correct result. fn repeat_expr_might_be_expanded(expr: &Expr<'_>) -> bool { - let ExprKind::Repeat(_, ArrayLen::Body(len_ct)) = expr.kind else { + let ExprKind::Repeat(_, len_ct) = expr.kind else { return false; }; !expr.span.contains(len_ct.span()) diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 1bf24083665f..51001d374b44 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -3,7 +3,7 @@ use rustc_ast::LitIntType; use rustc_ast::ast::{LitFloatType, LitKind}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::{ - self as hir, ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind, + self as hir, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -278,6 +278,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { chain!(self, "let ConstArgKind::Anon({anon_const}) = {const_arg}.kind"); self.body(field!(anon_const.body)); }, + ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), } } @@ -611,14 +612,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { bind!(self, value, length); kind!("Repeat({value}, {length})"); self.expr(value); - match length.value { - ArrayLen::Infer(..) => chain!(self, "let ArrayLen::Infer(..) = length"), - ArrayLen::Body(const_arg) => { - bind!(self, const_arg); - chain!(self, "let ArrayLen::Body({const_arg}) = {length}"); - self.const_arg(const_arg); - }, - } + self.const_arg(length); }, ExprKind::Err(_) => kind!("Err(_)"), ExprKind::DropTemps(expr) => { diff --git a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs index fdc1d06e67a1..05f856507697 100644 --- a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs @@ -5,7 +5,7 @@ use clippy_utils::visitors::for_each_expr_without_closures; use rustc_ast::LitKind; use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; -use rustc_hir::{ArrayLen, ConstArgKind, ExprKind, Node}; +use rustc_hir::{ConstArgKind, ExprKind, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::declare_lint_pass; @@ -60,8 +60,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects { // doesn't seem as confusing as `[f(); 0]`. It would also have false positives when eg. // the const item depends on `#[cfg]s` and has different values in different compilation // sessions). - else if let ExprKind::Repeat(inner_expr, length) = expr.kind - && let ArrayLen::Body(const_arg) = length + else if let ExprKind::Repeat(inner_expr, const_arg) = expr.kind && let ConstArgKind::Anon(anon_const) = const_arg.kind && let length_expr = hir_map.body(anon_const.body).value && !length_expr.span.from_expansion() diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 8a88a24e924c..7f3e331e7f64 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHasher; use rustc_hir::MatchSource::TryDesugar; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{ - ArrayLen, AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, + AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitBoundModifiers, Ty, TyKind, @@ -266,14 +266,6 @@ impl HirEqInterExpr<'_, '_, '_> { }) } - pub fn eq_array_length(&mut self, left: ArrayLen<'_>, right: ArrayLen<'_>) -> bool { - match (left, right) { - (ArrayLen::Infer(..), ArrayLen::Infer(..)) => true, - (ArrayLen::Body(l_ct), ArrayLen::Body(r_ct)) => self.eq_const_arg(l_ct, r_ct), - (_, _) => false, - } - } - pub fn eq_body(&mut self, left: BodyId, right: BodyId) -> bool { // swap out TypeckResults when hashing a body let old_maybe_typeck_results = self.inner.maybe_typeck_results.replace(( @@ -383,7 +375,7 @@ impl HirEqInterExpr<'_, '_, '_> { }, (ExprKind::Path(l), ExprKind::Path(r)) => self.eq_qpath(l, r), (&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => { - self.eq_expr(le, re) && self.eq_array_length(ll, rl) + self.eq_expr(le, re) && self.eq_const_arg(ll, rl) }, (ExprKind::Ret(l), ExprKind::Ret(r)) => both(l.as_ref(), r.as_ref(), |l, r| self.eq_expr(l, r)), (&ExprKind::Struct(l_path, lf, ref lo), &ExprKind::Struct(r_path, rf, ref ro)) => { @@ -469,8 +461,10 @@ impl HirEqInterExpr<'_, '_, '_> { match (&left.kind, &right.kind) { (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p), (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body), + (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true, // Use explicit match for now since ConstArg is undergoing flux. - (ConstArgKind::Path(..), ConstArgKind::Anon(..)) | (ConstArgKind::Anon(..), ConstArgKind::Path(..)) => { + (ConstArgKind::Path(..), ConstArgKind::Anon(..)) | (ConstArgKind::Anon(..), ConstArgKind::Path(..)) + | (ConstArgKind::Infer(..), _) | (_, ConstArgKind::Infer(..)) => { false }, } @@ -589,7 +583,7 @@ impl HirEqInterExpr<'_, '_, '_> { pub fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool { match (&left.kind, &right.kind) { (&TyKind::Slice(l_vec), &TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec), - (&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_array_length(ll, rl), + (&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_const_arg(ll, rl), (TyKind::Ptr(l_mut), TyKind::Ptr(r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty), (TyKind::Ref(_, l_rmut), TyKind::Ref(_, r_rmut)) => { l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty) @@ -1008,7 +1002,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { }, ExprKind::Repeat(e, len) => { self.hash_expr(e); - self.hash_array_length(len); + self.hash_const_arg(len); }, ExprKind::Ret(ref e) => { if let Some(e) = *e { @@ -1201,7 +1195,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { }, &TyKind::Array(ty, len) => { self.hash_ty(ty); - self.hash_array_length(len); + self.hash_const_arg(len); }, TyKind::Pat(ty, pat) => { self.hash_ty(ty); @@ -1252,13 +1246,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } } - pub fn hash_array_length(&mut self, length: ArrayLen<'_>) { - match length { - ArrayLen::Infer(..) => {}, - ArrayLen::Body(ct) => self.hash_const_arg(ct), - } - } - pub fn hash_body(&mut self, body_id: BodyId) { // swap out TypeckResults when hashing a body let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body_id)); @@ -1270,6 +1257,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { match &const_arg.kind { ConstArgKind::Path(path) => self.hash_qpath(path), ConstArgKind::Anon(anon) => self.hash_body(anon.body), + ConstArgKind::Infer(..) => {}, } } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 434c26d687d7..8d48cdd3cbb4 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -103,7 +103,7 @@ use rustc_hir::definitions::{DefPath, DefPathData}; use rustc_hir::hir_id::{HirIdMap, HirIdSet}; use rustc_hir::intravisit::{FnKind, Visitor, walk_expr}; use rustc_hir::{ - self as hir, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext, + self as hir, Arm, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, @@ -910,7 +910,7 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { _ => false, }, ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)), - ExprKind::Repeat(x, ArrayLen::Body(len)) => { + ExprKind::Repeat(x, len) => { if let ConstArgKind::Anon(anon_const) = len.kind && let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind && let LitKind::Int(v, _) = const_lit.node @@ -940,7 +940,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: & .. }) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String), ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec), - ExprKind::Repeat(_, ArrayLen::Body(len)) => { + ExprKind::Repeat(_, len) => { if let ConstArgKind::Anon(anon_const) = len.kind && let ExprKind::Lit(const_lit) = cx.tcx.hir().body(anon_const.body).value.kind && let LitKind::Int(v, _) = const_lit.node diff --git a/src/tools/clippy/tests/ui/author/repeat.stdout b/src/tools/clippy/tests/ui/author/repeat.stdout index d9e3f864f12f..1a608734ada9 100644 --- a/src/tools/clippy/tests/ui/author/repeat.stdout +++ b/src/tools/clippy/tests/ui/author/repeat.stdout @@ -1,8 +1,7 @@ if let ExprKind::Repeat(value, length) = expr.kind && let ExprKind::Lit(ref lit) = value.kind && let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node - && let ArrayLen::Body(const_arg) = length - && let ConstArgKind::Anon(anon_const) = const_arg.kind + && let ConstArgKind::Anon(anon_const) = length.kind && expr1 = &cx.tcx.hir().body(anon_const.body).value && let ExprKind::Lit(ref lit1) = expr1.kind && let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node