1
Fork 0

review comments: reword messages and simplify logic

This commit is contained in:
Esteban Küber 2024-12-04 20:49:05 +00:00
parent da58406c73
commit 4e6a401b22
10 changed files with 48 additions and 68 deletions

View file

@ -90,7 +90,7 @@ mir_build_const_param_in_pattern = constant parameters cannot be referenced in p
.label = can't be used in patterns .label = can't be used in patterns
mir_build_const_param_in_pattern_def = constant defined here mir_build_const_param_in_pattern_def = constant defined here
mir_build_const_pattern_depends_on_generic_parameter = constant pattern depends on a generic parameter, which is not allowed mir_build_const_pattern_depends_on_generic_parameter = constant pattern cannot depend on generic parameters
.label = `const` depends on a generic parameter .label = `const` depends on a generic parameter
mir_build_could_not_eval_const_pattern = could not evaluate constant pattern mir_build_could_not_eval_const_pattern = could not evaluate constant pattern

View file

@ -1,7 +1,7 @@
use rustc_abi::{FieldIdx, VariantIdx}; use rustc_abi::{FieldIdx, VariantIdx};
use rustc_apfloat::Float; use rustc_apfloat::Float;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Diag, PResult}; use rustc_errors::Diag;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_index::Idx; use rustc_index::Idx;
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
@ -42,10 +42,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
match c.kind() { match c.kind() {
ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty), ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
ty::ConstKind::Value(_, val) => match convert.valtree_to_pat(val, ty) { ty::ConstKind::Value(_, val) => convert.valtree_to_pat(val, ty),
Ok(pat) => pat,
Err(err) => convert.mk_err(err, ty),
},
_ => span_bug!(span, "Invalid `ConstKind` for `const_to_pat`: {:?}", c), _ => span_bug!(span, "Invalid `ConstKind` for `const_to_pat`: {:?}", c),
} }
} }
@ -151,7 +148,7 @@ impl<'tcx> ConstToPat<'tcx> {
let generics = self.tcx.generics_of(def_id); let generics = self.tcx.generics_of(def_id);
let param = generics.type_param(*param_ty, self.tcx); let param = generics.type_param(*param_ty, self.tcx);
let span = self.tcx.def_span(param.def_id); let span = self.tcx.def_span(param.def_id);
e.span_label(span, "constant depends on this generic param"); e.span_label(span, "constant depends on this generic parameter");
if let Some(ident) = self.tcx.def_ident_span(def_id) if let Some(ident) = self.tcx.def_ident_span(def_id)
&& self.tcx.sess.source_map().is_multiline(ident.between(span)) && self.tcx.sess.source_map().is_multiline(ident.between(span))
{ {
@ -184,10 +181,7 @@ impl<'tcx> ConstToPat<'tcx> {
}; };
// Convert the valtree to a const. // Convert the valtree to a const.
let inlined_const_as_pat = match self.valtree_to_pat(valtree, ty) { let inlined_const_as_pat = self.valtree_to_pat(valtree, ty);
Ok(pat) => pat,
Err(err) => self.mk_err(err, ty),
};
if !inlined_const_as_pat.references_error() { if !inlined_const_as_pat.references_error() {
// Always check for `PartialEq` if we had no other errors yet. // Always check for `PartialEq` if we had no other errors yet.
@ -210,20 +204,14 @@ impl<'tcx> ConstToPat<'tcx> {
let field = FieldIdx::new(idx); let field = FieldIdx::new(idx);
// Patterns can only use monomorphic types. // Patterns can only use monomorphic types.
let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty); let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty);
FieldPat { FieldPat { field, pattern: self.valtree_to_pat(val, ty) }
field,
pattern: match self.valtree_to_pat(val, ty) {
Ok(pat) => pat,
Err(err) => self.mk_err(err, ty),
},
}
}) })
.collect() .collect()
} }
// Recursive helper for `to_pat`; invoke that (instead of calling this directly). // Recursive helper for `to_pat`; invoke that (instead of calling this directly).
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> PResult<'_, Box<Pat<'tcx>>> { fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
let span = self.span; let span = self.span;
let tcx = self.tcx; let tcx = self.tcx;
let kind = match ty.kind() { let kind = match ty.kind() {
@ -231,12 +219,12 @@ impl<'tcx> ConstToPat<'tcx> {
// Extremely important check for all ADTs! Make sure they opted-in to be used in // Extremely important check for all ADTs! Make sure they opted-in to be used in
// patterns. // patterns.
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty); debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty);
let (impls_partial_eq, derived, structural, impl_def_id) = let (_impls_partial_eq, derived, structural, impl_def_id) =
type_has_partial_eq_impl(self.tcx, self.typing_env, ty); type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
let (manual_partialeq_impl_span, manual_partialeq_impl_note) = let (manual_partialeq_impl_span, manual_partialeq_impl_note) =
match (impls_partial_eq, derived, structural, impl_def_id) { match (structural, impl_def_id) {
(_, _, true, _) => (None, false), (true, _) => (None, false),
(_, false, _, Some(def_id)) if def_id.is_local() => { (_, Some(def_id)) if def_id.is_local() && !derived => {
(Some(tcx.def_span(def_id)), false) (Some(tcx.def_span(def_id)), false)
} }
_ => (None, true), _ => (None, true),
@ -249,7 +237,7 @@ impl<'tcx> ConstToPat<'tcx> {
manual_partialeq_impl_span, manual_partialeq_impl_span,
manual_partialeq_impl_note, manual_partialeq_impl_note,
}; };
return Err(tcx.dcx().create_err(err)); return self.mk_err(tcx.dcx().create_err(err), ty);
} }
ty::Adt(adt_def, args) if adt_def.is_enum() => { ty::Adt(adt_def, args) if adt_def.is_enum() => {
let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap(); let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap();
@ -283,10 +271,7 @@ impl<'tcx> ConstToPat<'tcx> {
prefix: cv prefix: cv
.unwrap_branch() .unwrap_branch()
.iter() .iter()
.map(|val| match self.valtree_to_pat(*val, *elem_ty) { .map(|val| self.valtree_to_pat(*val, *elem_ty))
Ok(pat) => pat,
Err(err) => self.mk_err(err, ty),
})
.collect(), .collect(),
slice: None, slice: None,
suffix: Box::new([]), suffix: Box::new([]),
@ -295,10 +280,7 @@ impl<'tcx> ConstToPat<'tcx> {
prefix: cv prefix: cv
.unwrap_branch() .unwrap_branch()
.iter() .iter()
.map(|val| match self.valtree_to_pat(*val, *elem_ty) { .map(|val| self.valtree_to_pat(*val, *elem_ty))
Ok(pat) => pat,
Err(err) => self.mk_err(err, ty),
})
.collect(), .collect(),
slice: None, slice: None,
suffix: Box::new([]), suffix: Box::new([]),
@ -314,9 +296,10 @@ impl<'tcx> ConstToPat<'tcx> {
// deref pattern. // deref pattern.
_ => { _ => {
if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() { if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() {
return Err(tcx return self.mk_err(
.dcx() tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }),
.create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty })); ty,
);
} else { } else {
// `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
// matching against references, you can only use byte string literals. // matching against references, you can only use byte string literals.
@ -331,10 +314,7 @@ impl<'tcx> ConstToPat<'tcx> {
_ => *pointee_ty, _ => *pointee_ty,
}; };
// References have the same valtree representation as their pointee. // References have the same valtree representation as their pointee.
let subpattern = match self.valtree_to_pat(cv, pointee_ty) { let subpattern = self.valtree_to_pat(cv, pointee_ty);
Ok(pat) => pat,
Err(err) => self.mk_err(err, ty),
};
PatKind::Deref { subpattern } PatKind::Deref { subpattern }
} }
} }
@ -350,7 +330,7 @@ impl<'tcx> ConstToPat<'tcx> {
if is_nan { if is_nan {
// NaNs are not ever equal to anything so they make no sense as patterns. // NaNs are not ever equal to anything so they make no sense as patterns.
// Also see <https://github.com/rust-lang/rfcs/pull/3535>. // Also see <https://github.com/rust-lang/rfcs/pull/3535>.
return Err(tcx.dcx().create_err(NaNPattern { span })); return self.mk_err(tcx.dcx().create_err(NaNPattern { span }), ty);
} else { } else {
PatKind::Constant { PatKind::Constant {
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)), value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
@ -373,16 +353,16 @@ impl<'tcx> ConstToPat<'tcx> {
non_sm_ty: ty, non_sm_ty: ty,
prefix: ty.prefix_string(tcx).to_string(), prefix: ty.prefix_string(tcx).to_string(),
}; };
return Err(tcx.dcx().create_err(err)); return self.mk_err(tcx.dcx().create_err(err), ty);
} }
}; };
Ok(Box::new(Pat { span, ty, kind })) Box::new(Pat { span, ty, kind })
} }
} }
/// Given a type with type parameters, visit every ADT looking for types that need to /// Given a type with type parameters, visit every ADT looking for types that need to
/// `#[derive(PartialEq)]` to be a structural type. /// `#[derive(PartialEq)]` for it to be a structural type.
fn extend_type_not_partial_eq<'tcx>( fn extend_type_not_partial_eq<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
typing_env: ty::TypingEnv<'tcx>, typing_env: ty::TypingEnv<'tcx>,

View file

@ -18,17 +18,17 @@ impl Foo for Def {
pub fn test<A: Foo, B: Foo>(arg: EFoo) { pub fn test<A: Foo, B: Foo>(arg: EFoo) {
match arg { match arg {
A::X => println!("A::X"), A::X => println!("A::X"),
//~^ error: constant pattern depends on a generic parameter //~^ ERROR constant pattern cannot depend on generic parameters
B::X => println!("B::X"), B::X => println!("B::X"),
//~^ error: constant pattern depends on a generic parameter //~^ ERROR constant pattern cannot depend on generic parameters
_ => (), _ => (),
} }
} }
pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern cannot depend on generic parameters
let A::X = arg; let A::X = arg;
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern cannot depend on generic parameters
} }
fn main() { fn main() {

View file

@ -1,4 +1,4 @@
error[E0158]: constant pattern depends on a generic parameter, which is not allowed error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/associated-const-type-parameter-pattern.rs:20:9 --> $DIR/associated-const-type-parameter-pattern.rs:20:9
| |
LL | pub trait Foo { LL | pub trait Foo {
@ -7,12 +7,12 @@ LL | const X: EFoo;
| ------------- constant defined here | ------------- constant defined here
... ...
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) { LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
| - constant depends on this generic param | - constant depends on this generic parameter
LL | match arg { LL | match arg {
LL | A::X => println!("A::X"), LL | A::X => println!("A::X"),
| ^^^^ `const` depends on a generic parameter | ^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter, which is not allowed error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/associated-const-type-parameter-pattern.rs:22:9 --> $DIR/associated-const-type-parameter-pattern.rs:22:9
| |
LL | pub trait Foo { LL | pub trait Foo {
@ -21,12 +21,12 @@ LL | const X: EFoo;
| ------------- constant defined here | ------------- constant defined here
... ...
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) { LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
| - constant depends on this generic param | - constant depends on this generic parameter
... ...
LL | B::X => println!("B::X"), LL | B::X => println!("B::X"),
| ^^^^ `const` depends on a generic parameter | ^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter, which is not allowed error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/associated-const-type-parameter-pattern.rs:30:9 --> $DIR/associated-const-type-parameter-pattern.rs:30:9
| |
LL | pub trait Foo { LL | pub trait Foo {
@ -35,12 +35,12 @@ LL | const X: EFoo;
| ------------- constant defined here | ------------- constant defined here
... ...
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
| - constant depends on this generic param | - constant depends on this generic parameter
LL | LL |
LL | let A::X = arg; LL | let A::X = arg;
| ^^^^ `const` depends on a generic parameter | ^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter, which is not allowed error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/associated-const-type-parameter-pattern.rs:28:48 --> $DIR/associated-const-type-parameter-pattern.rs:28:48
| |
LL | pub trait Foo { LL | pub trait Foo {
@ -51,7 +51,7 @@ LL | const X: EFoo;
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) { LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
| - ^^^^ `const` depends on a generic parameter | - ^^^^ `const` depends on a generic parameter
| | | |
| constant depends on this generic param | constant depends on this generic parameter
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -18,7 +18,7 @@ impl<T: 'static> GetTypeId<T> {
const fn check_type_id<T: 'static>() -> bool { const fn check_type_id<T: 'static>() -> bool {
matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern cannot depend on generic parameters
} }
pub struct GetTypeNameLen<T>(T); pub struct GetTypeNameLen<T>(T);
@ -29,7 +29,7 @@ impl<T: 'static> GetTypeNameLen<T> {
const fn check_type_name_len<T: 'static>() -> bool { const fn check_type_name_len<T: 'static>() -> bool {
matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern cannot depend on generic parameters
} }
fn main() { fn main() {

View file

@ -1,4 +1,4 @@
error[E0158]: constant pattern depends on a generic parameter, which is not allowed error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/issue-73976-polymorphic.rs:20:37 --> $DIR/issue-73976-polymorphic.rs:20:37
| |
LL | impl<T: 'static> GetTypeId<T> { LL | impl<T: 'static> GetTypeId<T> {
@ -7,11 +7,11 @@ LL | pub const VALUE: TypeId = TypeId::of::<T>();
| ----------------------- constant defined here | ----------------------- constant defined here
... ...
LL | const fn check_type_id<T: 'static>() -> bool { LL | const fn check_type_id<T: 'static>() -> bool {
| - constant depends on this generic param | - constant depends on this generic parameter
LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) LL | matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter | ^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter, which is not allowed error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/issue-73976-polymorphic.rs:31:42 --> $DIR/issue-73976-polymorphic.rs:31:42
| |
LL | impl<T: 'static> GetTypeNameLen<T> { LL | impl<T: 'static> GetTypeNameLen<T> {
@ -20,7 +20,7 @@ LL | pub const VALUE: usize = any::type_name::<T>().len();
| ---------------------- constant defined here | ---------------------- constant defined here
... ...
LL | const fn check_type_name_len<T: 'static>() -> bool { LL | const fn check_type_name_len<T: 'static>() -> bool {
| - constant depends on this generic param | - constant depends on this generic parameter
LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) LL | matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter

View file

@ -10,7 +10,7 @@ impl<T> GetVariantCount<T> {
const fn check_variant_count<T>() -> bool { const fn check_variant_count<T>() -> bool {
matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE) matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern cannot depend on generic parameters
} }
fn main() { fn main() {

View file

@ -1,4 +1,4 @@
error[E0158]: constant pattern depends on a generic parameter, which is not allowed error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/issue-79137-toogeneric.rs:12:43 --> $DIR/issue-79137-toogeneric.rs:12:43
| |
LL | impl<T> GetVariantCount<T> { LL | impl<T> GetVariantCount<T> {
@ -7,7 +7,7 @@ LL | pub const VALUE: usize = std::mem::variant_count::<T>();
| ---------------------- constant defined here | ---------------------- constant defined here
... ...
LL | const fn check_variant_count<T>() -> bool { LL | const fn check_variant_count<T>() -> bool {
| - constant depends on this generic param | - constant depends on this generic parameter
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE) LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `const` depends on a generic parameter

View file

@ -5,7 +5,7 @@
fn foo<const V: usize>() { fn foo<const V: usize>() {
match 0 { match 0 {
const { V } => {}, const { V } => {},
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern cannot depend on generic parameters
_ => {}, _ => {},
} }
} }
@ -17,7 +17,7 @@ const fn f(x: usize) -> usize {
fn bar<const V: usize>() { fn bar<const V: usize>() {
match 0 { match 0 {
const { f(V) } => {}, const { f(V) } => {},
//~^ ERROR constant pattern depends on a generic parameter //~^ ERROR constant pattern cannot depend on generic parameters
_ => {}, _ => {},
} }
} }

View file

@ -1,10 +1,10 @@
error[E0158]: constant pattern depends on a generic parameter, which is not allowed error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/const-match-pat-generic.rs:7:9 --> $DIR/const-match-pat-generic.rs:7:9
| |
LL | const { V } => {}, LL | const { V } => {},
| ^^^^^^^^^^^ `const` depends on a generic parameter | ^^^^^^^^^^^ `const` depends on a generic parameter
error[E0158]: constant pattern depends on a generic parameter, which is not allowed error[E0158]: constant pattern cannot depend on generic parameters
--> $DIR/const-match-pat-generic.rs:19:9 --> $DIR/const-match-pat-generic.rs:19:9
| |
LL | const { f(V) } => {}, LL | const { f(V) } => {},