Skip to content

Commit

Permalink
Auto merge of #64360 - varkor:foreign-items-diagnostic-const-generics…
Browse files Browse the repository at this point in the history
…, r=cramertj

Correct the polymorphic extern fn error for const parameters

Before, any polymorphism on extern functions was assumed to be type polymorphism.
  • Loading branch information
bors committed Sep 12, 2019
2 parents eb48d6b + ef62e05 commit a5e3de3
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 15 deletions.
37 changes: 25 additions & 12 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1511,21 +1511,34 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
} else {
for item in &m.items {
let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
if generics.params.len() - generics.own_counts().lifetimes != 0 {
let mut err = struct_span_err!(
let own_counts = generics.own_counts();
if generics.params.len() - own_counts.lifetimes != 0 {
let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
(_, 0) => ("type", "types", Some("u32")),
// We don't specify an example value, because we can't generate
// a valid value for any type.
(0, _) => ("const", "consts", None),
_ => ("type or const", "types or consts", None),
};
struct_span_err!(
tcx.sess,
item.span,
E0044,
"foreign items may not have type parameters"
);
err.span_label(item.span, "can't have type parameters");
// FIXME: once we start storing spans for type arguments, turn this into a
// suggestion.
err.help(
"use specialization instead of type parameters by replacing them \
with concrete types like `u32`",
);
err.emit();
"foreign items may not have {} parameters",
kinds,
).span_label(
item.span,
&format!("can't have {} parameters", kinds),
).help(
// FIXME: once we start storing spans for type arguments, turn this
// into a suggestion.
&format!(
"replace the {} parameters with concrete {}{}",
kinds,
kinds_pl,
egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
),
).emit();
}

if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.node {
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/const-generics/foreign-item-const-parameter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash

extern "C" {
fn foo<const X: usize>(); //~ ERROR foreign items may not have const parameters

fn bar<T, const X: usize>(_: T); //~ ERROR foreign items may not have type or const parameters
}

fn main() {}
27 changes: 27 additions & 0 deletions src/test/ui/const-generics/foreign-item-const-parameter.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/foreign-item-const-parameter.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0044]: foreign items may not have const parameters
--> $DIR/foreign-item-const-parameter.rs:5:5
|
LL | fn foo<const X: usize>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters
|
= help: replace the const parameters with concrete consts

error[E0044]: foreign items may not have type or const parameters
--> $DIR/foreign-item-const-parameter.rs:7:5
|
LL | fn bar<T, const X: usize>(_: T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have type or const parameters
|
= help: replace the type or const parameters with concrete types or consts

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0044`.
2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0044.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern {
fn sqrt<T>(f: T) -> T;
//~^ ERROR foreign items may not have type parameters [E0044]
//~| HELP use specialization instead of type parameters by replacing them with concrete types
//~| HELP replace the type parameters with concrete types
//~| NOTE can't have type parameters
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0044.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0044]: foreign items may not have type parameters
LL | fn sqrt<T>(f: T) -> T;
| ^^^^^^^^^^^^^^^^^^^^^^ can't have type parameters
|
= help: use specialization instead of type parameters by replacing them with concrete types like `u32`
= help: replace the type parameters with concrete types like `u32`

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/generic/generic-extern.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0044]: foreign items may not have type parameters
LL | fn foo<T>();
| ^^^^^^^^^^^^ can't have type parameters
|
= help: use specialization instead of type parameters by replacing them with concrete types like `u32`
= help: replace the type parameters with concrete types like `u32`

error: aborting due to previous error

Expand Down

0 comments on commit a5e3de3

Please sign in to comment.