mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-12 20:16:49 +00:00
Auto merge of #133728 - jhpratt:rollup-k1i60pg, r=jhpratt
Rollup of 4 pull requests Successful merges: - #133589 (Remove `hir::ArrayLen`) - #133672 (Remove a bunch of unnecessary const stability noise) - #133678 (Stabilize `ptr::fn_addr_eq`) - #133727 (Update mailmap) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
3bff51ea91
1
.mailmap
1
.mailmap
@ -254,6 +254,7 @@ Jack Huey <jack.huey@umassmed.edu> <jackh726@gmail.com>
|
||||
Jacob <jacob.macritchie@gmail.com>
|
||||
Jacob Greenfield <xales@naveria.com>
|
||||
Jacob Pratt <jacob@jhpratt.dev> <the.z.cuber@gmail.com>
|
||||
Jacob Pratt <jacob@jhpratt.dev> <jacopratt@tesla.com>
|
||||
Jake Vossen <jake@vossen.dev>
|
||||
Jakob Degen <jakob.e.degen@gmail.com> <jakob@degen.com>
|
||||
Jakob Lautrup Nysom <jako3047@gmail.com>
|
||||
|
@ -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)),
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<LitKind>;
|
||||
|
||||
#[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 <expr>`).
|
||||
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,
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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"),
|
||||
|
@ -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(),
|
||||
|
@ -486,7 +486,6 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
|
||||
/// 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<T, A> {
|
||||
BinaryHeap { data: Vec::new_in(alloc) }
|
||||
|
@ -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)]
|
||||
|
@ -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)]
|
||||
|
@ -713,7 +713,6 @@ impl<T, const N: usize> Cell<[T; N]> {
|
||||
/// let array_cell: &[Cell<i32>; 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<T>; N] {
|
||||
// SAFETY: `Cell<T>` has the same memory layout as `T`.
|
||||
unsafe { &*(self as *const Cell<[T; N]> as *const [Cell<T>; N]) }
|
||||
|
@ -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)]
|
||||
|
@ -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, \
|
||||
|
@ -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 {
|
||||
|
@ -346,7 +346,6 @@ impl<T: ?Sized> *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<T>>
|
||||
where
|
||||
T: Sized,
|
||||
@ -1528,7 +1527,6 @@ impl<T> *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<const N: usize>(self) -> Option<*const [T; N]> {
|
||||
@ -1608,7 +1606,6 @@ impl<T> *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<T>]> {
|
||||
if self.is_null() {
|
||||
None
|
||||
|
@ -2111,7 +2111,6 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(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<T: ?Sized, U: ?Sized>(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<T: ?Sized, U: ?Sized>(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<T: FnPtr, U: FnPtr>(f: T, g: U) -> bool {
|
||||
|
@ -342,7 +342,6 @@ impl<T: ?Sized> *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<T>>
|
||||
where
|
||||
T: Sized,
|
||||
@ -676,7 +675,6 @@ impl<T: ?Sized> *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<T>>
|
||||
where
|
||||
T: Sized,
|
||||
@ -1762,7 +1760,6 @@ impl<T> *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<const N: usize>(self) -> Option<*mut [T; N]> {
|
||||
@ -1963,7 +1960,6 @@ impl<T> *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<T>]> {
|
||||
if self.is_null() {
|
||||
None
|
||||
@ -2015,7 +2011,6 @@ impl<T> *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<T>]> {
|
||||
if self.is_null() {
|
||||
None
|
||||
|
@ -92,6 +92,7 @@ impl<T: ?Sized> Unique<T> {
|
||||
|
||||
/// 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<Self> {
|
||||
if let Some(pointer) = NonNull::new(ptr) {
|
||||
|
@ -860,7 +860,6 @@ impl<T> [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<const N: usize>(&self) -> Option<&[T; N]> {
|
||||
@ -879,7 +878,6 @@ impl<T> [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<const N: usize>(&mut self) -> Option<&mut [T; N]> {
|
||||
|
@ -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)]
|
||||
|
@ -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)]
|
||||
|
@ -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]
|
||||
|
@ -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()),
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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) => {
|
||||
|
@ -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()
|
||||
|
@ -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(..) => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user