diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2024-11-20 03:08:52 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2024-12-04 20:29:36 +0000 |
| commit | 87ddc1ea33edbe1be119d73e57c2783940e797fe (patch) | |
| tree | 1078cb612921aa307c2700910e38c4441beccbd8 /compiler | |
| parent | c0f00086f85ae1fff34dd2daf6a11850e5bfc2f0 (diff) | |
| download | rust-87ddc1ea33edbe1be119d73e57c2783940e797fe.tar.gz rust-87ddc1ea33edbe1be119d73e57c2783940e797fe.zip | |
Point at generic param through which a const is used in a pattern
```
error[E0158]: constant pattern depends on a generic parameter, which is not allowed
--> $DIR/associated-const-type-parameter-pattern.rs:20:9
|
LL | pub trait Foo {
| -------------
LL | const X: EFoo;
| ------------- constant defined here
...
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
| - constant depends on this generic param
LL | match arg {
LL | A::X => println!("A::X"),
| ^^^^ `const` depends on a generic parameter
```
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_mir_build/messages.ftl | 4 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/errors.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 22 |
3 files changed, 24 insertions, 3 deletions
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 2bf49137e8f..4bc7dcf9564 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -88,8 +88,8 @@ mir_build_const_defined_here = constant defined here mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns -mir_build_const_pattern_depends_on_generic_parameter = - constant pattern depends on a generic parameter +mir_build_const_pattern_depends_on_generic_parameter = constant pattern depends on a generic parameter, which is not allowed + .label = `const` depends on a generic parameter mir_build_could_not_eval_const_pattern = could not evaluate constant pattern .label = could not evaluate constant diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 7f4bb139fad..1068c56eeca 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -695,6 +695,7 @@ pub(crate) struct WantedConstant { #[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)] pub(crate) struct ConstPatternDependsOnGenericParameter { #[primary_span] + #[label] pub(crate) span: Span, } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 3690459bf51..b625c655fac 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -53,6 +53,7 @@ struct ConstToPat<'tcx> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, span: Span, + id: hir::HirId, treat_byte_string_as_slice: bool, @@ -66,6 +67,7 @@ impl<'tcx> ConstToPat<'tcx> { tcx: pat_ctxt.tcx, typing_env: pat_ctxt.typing_env, span, + id, treat_byte_string_as_slice: pat_ctxt .typeck_results .treat_byte_string_as_slice @@ -135,10 +137,28 @@ impl<'tcx> ConstToPat<'tcx> { return self.mk_err(err, ty); } Err(ErrorHandled::TooGeneric(_)) => { - let e = self + let mut e = self .tcx .dcx() .create_err(ConstPatternDependsOnGenericParameter { span: self.span }); + for arg in uv.args { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Param(param_ty) = ty.kind() + { + let def_id = self.tcx.hir().enclosing_body_owner(self.id); + let generics = self.tcx.generics_of(def_id); + let param = generics.type_param(*param_ty, self.tcx); + let span = self.tcx.def_span(param.def_id); + e.span_label(span, "constant depends on this generic param"); + if let Some(ident) = self.tcx.def_ident_span(def_id) + && self.tcx.sess.source_map().is_multiline(ident.between(span)) + { + // Display the `fn` name as well in the diagnostic, as the generic isn't + // in the same line and it could be confusing otherwise. + e.span_label(ident, ""); + } + } + } return self.mk_err(e, ty); } Ok(Err(bad_ty)) => { |
