From 14e6947fa4b9a144802869286a937c987d6a3c54 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 10 Sep 2019 18:46:27 +0100 Subject: [PATCH 1/2] Correct the polymorphic extern fn error for const parameters --- src/librustc_typeck/check/mod.rs | 33 +++++++++++++++---- .../foreign-item-const-parameter.rs | 10 ++++++ .../foreign-item-const-parameter.stderr | 27 +++++++++++++++ 3 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/const-generics/foreign-item-const-parameter.rs create mode 100644 src/test/ui/const-generics/foreign-item-const-parameter.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d8d01624f1d56..e76ef14f06c87 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1511,20 +1511,39 @@ 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 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), + }; let mut err = struct_span_err!( tcx.sess, item.span, E0044, - "foreign items may not have type parameters" + "foreign items may not have {} parameters", + kinds, + ); + err.span_label( + item.span, + &format!("can't have {} parameters", kinds), ); - 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.help(&format!( + "use specialization instead of {} parameters by replacing \ + them with concrete {}{}", + kinds, + kinds_pl, + if let Some(egs) = egs { + format!(" like `{}`", egs) + } else { + "".to_string() + }, + )); err.emit(); } diff --git a/src/test/ui/const-generics/foreign-item-const-parameter.rs b/src/test/ui/const-generics/foreign-item-const-parameter.rs new file mode 100644 index 0000000000000..4673c8606c393 --- /dev/null +++ b/src/test/ui/const-generics/foreign-item-const-parameter.rs @@ -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(); //~ ERROR foreign items may not have const parameters + + fn bar(_: T); //~ ERROR foreign items may not have type or const parameters +} + +fn main() {} diff --git a/src/test/ui/const-generics/foreign-item-const-parameter.stderr b/src/test/ui/const-generics/foreign-item-const-parameter.stderr new file mode 100644 index 0000000000000..0a74537dfef35 --- /dev/null +++ b/src/test/ui/const-generics/foreign-item-const-parameter.stderr @@ -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(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters + | + = help: use specialization instead of const parameters by replacing them 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); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have type or const parameters + | + = help: use specialization instead of type or const parameters by replacing them with concrete types or consts + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0044`. From ef62e050624fabc57f17dd6744ff29f79b39e8cd Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 10 Sep 2019 22:35:10 +0100 Subject: [PATCH 2/2] Make wording less confusing --- src/librustc_typeck/check/mod.rs | 30 ++++++++----------- .../foreign-item-const-parameter.stderr | 4 +-- src/test/ui/error-codes/E0044.rs | 2 +- src/test/ui/error-codes/E0044.stderr | 2 +- src/test/ui/generic/generic-extern.stderr | 2 +- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e76ef14f06c87..02e7d97ccdf7b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1520,31 +1520,25 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) { (0, _) => ("const", "consts", None), _ => ("type or const", "types or consts", None), }; - let mut err = struct_span_err!( + struct_span_err!( tcx.sess, item.span, E0044, "foreign items may not have {} parameters", kinds, - ); - err.span_label( + ).span_label( item.span, &format!("can't have {} parameters", kinds), - ); - // FIXME: once we start storing spans for type arguments, turn this into a - // suggestion. - err.help(&format!( - "use specialization instead of {} parameters by replacing \ - them with concrete {}{}", - kinds, - kinds_pl, - if let Some(egs) = egs { - format!(" like `{}`", egs) - } else { - "".to_string() - }, - )); - err.emit(); + ).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 { diff --git a/src/test/ui/const-generics/foreign-item-const-parameter.stderr b/src/test/ui/const-generics/foreign-item-const-parameter.stderr index 0a74537dfef35..999feed2d3b20 100644 --- a/src/test/ui/const-generics/foreign-item-const-parameter.stderr +++ b/src/test/ui/const-generics/foreign-item-const-parameter.stderr @@ -12,7 +12,7 @@ error[E0044]: foreign items may not have const parameters LL | fn foo(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters | - = help: use specialization instead of const parameters by replacing them with concrete consts + = 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 @@ -20,7 +20,7 @@ error[E0044]: foreign items may not have type or const parameters LL | fn bar(_: T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have type or const parameters | - = help: use specialization instead of type or const parameters by replacing them with concrete types or consts + = help: replace the type or const parameters with concrete types or consts error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0044.rs b/src/test/ui/error-codes/E0044.rs index a5265e7dc1708..9eee9c31d3c38 100644 --- a/src/test/ui/error-codes/E0044.rs +++ b/src/test/ui/error-codes/E0044.rs @@ -1,7 +1,7 @@ extern { fn sqrt(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 } diff --git a/src/test/ui/error-codes/E0044.stderr b/src/test/ui/error-codes/E0044.stderr index 57c21116b2856..e889c167b98d2 100644 --- a/src/test/ui/error-codes/E0044.stderr +++ b/src/test/ui/error-codes/E0044.stderr @@ -4,7 +4,7 @@ error[E0044]: foreign items may not have type parameters LL | fn sqrt(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 diff --git a/src/test/ui/generic/generic-extern.stderr b/src/test/ui/generic/generic-extern.stderr index e7625abb1c831..c90215b612d4c 100644 --- a/src/test/ui/generic/generic-extern.stderr +++ b/src/test/ui/generic/generic-extern.stderr @@ -4,7 +4,7 @@ error[E0044]: foreign items may not have type parameters LL | fn foo(); | ^^^^^^^^^^^^ 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