Skip to content

Commit 3b4589a

Browse files
committed
simplify const params diagnostic on stable
1 parent dd38eea commit 3b4589a

File tree

5 files changed

+86
-90
lines changed

5 files changed

+86
-90
lines changed

Diff for: compiler/rustc_typeck/src/check/wfcheck.rs

+82-70
Original file line numberDiff line numberDiff line change
@@ -816,16 +816,69 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
816816
hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
817817
let ty = tcx.type_of(tcx.hir().local_def_id(param.hir_id));
818818

819-
let err_ty_str;
820-
let mut is_ptr = true;
821-
let err = if tcx.features().adt_const_params {
822-
match ty.peel_refs().kind() {
819+
if tcx.features().adt_const_params {
820+
let err = match ty.peel_refs().kind() {
823821
ty::FnPtr(_) => Some("function pointers"),
824822
ty::RawPtr(_) => Some("raw pointers"),
825823
_ => None,
824+
};
825+
826+
if let Some(unsupported_type) = err {
827+
tcx.sess.span_err(
828+
hir_ty.span,
829+
&format!(
830+
"using {} as const generic parameters is forbidden",
831+
unsupported_type
832+
),
833+
);
834+
}
835+
836+
if traits::search_for_structural_match_violation(param.span, tcx, ty).is_some() {
837+
// We use the same error code in both branches, because this is really the same
838+
// issue: we just special-case the message for type parameters to make it
839+
// clearer.
840+
if let ty::Param(_) = ty.peel_refs().kind() {
841+
// Const parameters may not have type parameters as their types,
842+
// because we cannot be sure that the type parameter derives `PartialEq`
843+
// and `Eq` (just implementing them is not enough for `structural_match`).
844+
struct_span_err!(
845+
tcx.sess,
846+
hir_ty.span,
847+
E0741,
848+
"`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
849+
used as the type of a const parameter",
850+
ty,
851+
)
852+
.span_label(
853+
hir_ty.span,
854+
format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
855+
)
856+
.note(
857+
"it is not currently possible to use a type parameter as the type of a \
858+
const parameter",
859+
)
860+
.emit();
861+
} else {
862+
struct_span_err!(
863+
tcx.sess,
864+
hir_ty.span,
865+
E0741,
866+
"`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
867+
the type of a const parameter",
868+
ty,
869+
)
870+
.span_label(
871+
hir_ty.span,
872+
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
873+
)
874+
.emit();
875+
}
826876
}
827877
} else {
828-
match ty.kind() {
878+
let err_ty_str;
879+
let mut is_ptr = true;
880+
881+
let err = match ty.kind() {
829882
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
830883
ty::FnPtr(_) => Some("function pointers"),
831884
ty::RawPtr(_) => Some("raw pointers"),
@@ -834,74 +887,33 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
834887
err_ty_str = format!("`{}`", ty);
835888
Some(err_ty_str.as_str())
836889
}
837-
}
838-
};
839-
if let Some(unsupported_type) = err {
840-
if is_ptr {
841-
tcx.sess.span_err(
842-
hir_ty.span,
843-
&format!(
844-
"using {} as const generic parameters is forbidden",
845-
unsupported_type
846-
),
847-
);
848-
} else {
849-
let mut err = tcx.sess.struct_span_err(
850-
hir_ty.span,
851-
&format!(
852-
"{} is forbidden as the type of a const generic parameter",
853-
unsupported_type
854-
),
855-
);
856-
err.note("the only supported types are integers, `bool` and `char`");
857-
if tcx.sess.is_nightly_build() {
858-
err.help(
890+
};
891+
892+
if let Some(unsupported_type) = err {
893+
if is_ptr {
894+
tcx.sess.span_err(
895+
hir_ty.span,
896+
&format!(
897+
"using {} as const generic parameters is forbidden",
898+
unsupported_type
899+
),
900+
);
901+
} else {
902+
let mut err = tcx.sess.struct_span_err(
903+
hir_ty.span,
904+
&format!(
905+
"{} is forbidden as the type of a const generic parameter",
906+
unsupported_type
907+
),
908+
);
909+
err.note("the only supported types are integers, `bool` and `char`");
910+
if tcx.sess.is_nightly_build() {
911+
err.help(
859912
"more complex types are supported with `#![feature(adt_const_params)]`",
860913
);
914+
}
915+
err.emit();
861916
}
862-
err.emit();
863-
}
864-
};
865-
866-
if traits::search_for_structural_match_violation(param.span, tcx, ty).is_some() {
867-
// We use the same error code in both branches, because this is really the same
868-
// issue: we just special-case the message for type parameters to make it
869-
// clearer.
870-
if let ty::Param(_) = ty.peel_refs().kind() {
871-
// Const parameters may not have type parameters as their types,
872-
// because we cannot be sure that the type parameter derives `PartialEq`
873-
// and `Eq` (just implementing them is not enough for `structural_match`).
874-
struct_span_err!(
875-
tcx.sess,
876-
hir_ty.span,
877-
E0741,
878-
"`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
879-
used as the type of a const parameter",
880-
ty,
881-
)
882-
.span_label(
883-
hir_ty.span,
884-
format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
885-
)
886-
.note(
887-
"it is not currently possible to use a type parameter as the type of a \
888-
const parameter",
889-
)
890-
.emit();
891-
} else {
892-
struct_span_err!(
893-
tcx.sess,
894-
hir_ty.span,
895-
E0741,
896-
"`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
897-
the type of a const parameter",
898-
ty,
899-
)
900-
.span_label(
901-
hir_ty.span,
902-
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
903-
)
904-
.emit();
905917
}
906918
}
907919
}

Diff for: src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr

+1-8
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,5 @@ LL | fn test<const T: &'static dyn A>() {
77
= note: the only supported types are integers, `bool` and `char`
88
= help: more complex types are supported with `#![feature(adt_const_params)]`
99

10-
error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
11-
--> $DIR/issue-63322-forbid-dyn.rs:9:18
12-
|
13-
LL | fn test<const T: &'static dyn A>() {
14-
| ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq`
15-
16-
error: aborting due to 2 previous errors
10+
error: aborting due to previous error
1711

18-
For more information about this error, try `rustc --explain E0741`.

Diff for: src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct B;
77
impl A for B {}
88

99
fn test<const T: &'static dyn A>() {
10-
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used
10+
//[full]~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used
1111
//[min]~^^ ERROR `&'static (dyn A + 'static)` is forbidden
1212
unimplemented!()
1313
}

Diff for: src/test/ui/const-generics/nested-type.min.stderr

+1-10
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,5 @@ LL | | }]>;
1414
= note: the only supported types are integers, `bool` and `char`
1515
= help: more complex types are supported with `#![feature(adt_const_params)]`
1616

17-
error[E0015]: cannot call non-const fn `Foo::{constant#0}::Foo::<17_usize>::value` in constants
18-
--> $DIR/nested-type.rs:15:5
19-
|
20-
LL | Foo::<17>::value()
21-
| ^^^^^^^^^^^^^^^^^^
22-
|
23-
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
24-
25-
error: aborting due to 2 previous errors
17+
error: aborting due to previous error
2618

27-
For more information about this error, try `rustc --explain E0015`.

Diff for: src/test/ui/const-generics/nested-type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct Foo<const N: [u8; { //[min]~ ERROR `[u8; _]` is forbidden
1313
}
1414

1515
Foo::<17>::value()
16-
//~^ ERROR cannot call non-const fn
16+
//[full]~^ ERROR cannot call non-const fn
1717
}]>;
1818

1919
fn main() {}

0 commit comments

Comments
 (0)