Skip to content

Commit a5e3de3

Browse files
committed
Auto merge of #64360 - varkor:foreign-items-diagnostic-const-generics, r=cramertj
Correct the polymorphic extern fn error for const parameters Before, any polymorphism on extern functions was assumed to be type polymorphism.
2 parents eb48d6b + ef62e05 commit a5e3de3

File tree

6 files changed

+65
-15
lines changed

6 files changed

+65
-15
lines changed

Diff for: src/librustc_typeck/check/mod.rs

+25-12
Original file line numberDiff line numberDiff line change
@@ -1511,21 +1511,34 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
15111511
} else {
15121512
for item in &m.items {
15131513
let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
1514-
if generics.params.len() - generics.own_counts().lifetimes != 0 {
1515-
let mut err = struct_span_err!(
1514+
let own_counts = generics.own_counts();
1515+
if generics.params.len() - own_counts.lifetimes != 0 {
1516+
let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
1517+
(_, 0) => ("type", "types", Some("u32")),
1518+
// We don't specify an example value, because we can't generate
1519+
// a valid value for any type.
1520+
(0, _) => ("const", "consts", None),
1521+
_ => ("type or const", "types or consts", None),
1522+
};
1523+
struct_span_err!(
15161524
tcx.sess,
15171525
item.span,
15181526
E0044,
1519-
"foreign items may not have type parameters"
1520-
);
1521-
err.span_label(item.span, "can't have type parameters");
1522-
// FIXME: once we start storing spans for type arguments, turn this into a
1523-
// suggestion.
1524-
err.help(
1525-
"use specialization instead of type parameters by replacing them \
1526-
with concrete types like `u32`",
1527-
);
1528-
err.emit();
1527+
"foreign items may not have {} parameters",
1528+
kinds,
1529+
).span_label(
1530+
item.span,
1531+
&format!("can't have {} parameters", kinds),
1532+
).help(
1533+
// FIXME: once we start storing spans for type arguments, turn this
1534+
// into a suggestion.
1535+
&format!(
1536+
"replace the {} parameters with concrete {}{}",
1537+
kinds,
1538+
kinds_pl,
1539+
egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
1540+
),
1541+
).emit();
15291542
}
15301543

15311544
if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.node {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![feature(const_generics)]
2+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
3+
4+
extern "C" {
5+
fn foo<const X: usize>(); //~ ERROR foreign items may not have const parameters
6+
7+
fn bar<T, const X: usize>(_: T); //~ ERROR foreign items may not have type or const parameters
8+
}
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/foreign-item-const-parameter.rs:1:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
9+
error[E0044]: foreign items may not have const parameters
10+
--> $DIR/foreign-item-const-parameter.rs:5:5
11+
|
12+
LL | fn foo<const X: usize>();
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters
14+
|
15+
= help: replace the const parameters with concrete consts
16+
17+
error[E0044]: foreign items may not have type or const parameters
18+
--> $DIR/foreign-item-const-parameter.rs:7:5
19+
|
20+
LL | fn bar<T, const X: usize>(_: T);
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have type or const parameters
22+
|
23+
= help: replace the type or const parameters with concrete types or consts
24+
25+
error: aborting due to 2 previous errors
26+
27+
For more information about this error, try `rustc --explain E0044`.

Diff for: src/test/ui/error-codes/E0044.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
extern {
22
fn sqrt<T>(f: T) -> T;
33
//~^ ERROR foreign items may not have type parameters [E0044]
4-
//~| HELP use specialization instead of type parameters by replacing them with concrete types
4+
//~| HELP replace the type parameters with concrete types
55
//~| NOTE can't have type parameters
66
}
77

Diff for: src/test/ui/error-codes/E0044.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0044]: foreign items may not have type parameters
44
LL | fn sqrt<T>(f: T) -> T;
55
| ^^^^^^^^^^^^^^^^^^^^^^ can't have type parameters
66
|
7-
= help: use specialization instead of type parameters by replacing them with concrete types like `u32`
7+
= help: replace the type parameters with concrete types like `u32`
88

99
error: aborting due to previous error
1010

Diff for: src/test/ui/generic/generic-extern.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0044]: foreign items may not have type parameters
44
LL | fn foo<T>();
55
| ^^^^^^^^^^^^ can't have type parameters
66
|
7-
= help: use specialization instead of type parameters by replacing them with concrete types like `u32`
7+
= help: replace the type parameters with concrete types like `u32`
88

99
error: aborting due to previous error
1010

0 commit comments

Comments
 (0)