Rollup merge of #120556 - fmease:improve-unused-generic-param-diags, r=oli-obk

Improve the diagnostics for unused generic parameters

* Don't emit two errors (namely E0091 *and* E0392) for unused type parameters on *lazy* type aliases
* Fix the diagnostic help message of E0392 for *lazy* type aliases: Don't talk about the “fields” of lazy type aliases (use the term “body” instead) and don't suggest `PhantomData` for them, it doesn't make much sense
* Consolidate the diagnostics for E0091 (unused type parameters in type aliases) and E0392 (unused generic parameters due to bivariance) and make it translatable
  * Still keep the error codes distinct (for now)
  * Naturally leads to better diagnostics for E0091

r? ```@oli-obk``` (to ballast your review load :P) or compiler
This commit is contained in:
Matthias Krüger 2024-02-04 19:42:12 +01:00 committed by GitHub
commit 7fa99bfb71
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 370 additions and 170 deletions

View file

@ -1,11 +1,11 @@
An unnecessary type or const parameter was given in a type alias.
An unnecessary type parameter was given in a type alias.
Erroneous code example:
```compile_fail,E0091
type Foo<T> = u32; // error: type parameter `T` is unused
type Foo<T> = u32; // error: type parameter `T` is never used
// or:
type Foo<A,B> = Box<A>; // error: type parameter `B` is unused
type Foo<A, B> = Box<A>; // error: type parameter `B` is never used
```
Please check you didn't write too many parameters. Example:

View file

@ -434,6 +434,17 @@ hir_analysis_unused_associated_type_bounds =
.note = this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
.suggestion = remove this bound
hir_analysis_unused_generic_parameter =
{$param_def_kind} `{$param_name}` is never used
.label = unused {$param_def_kind}
.const_param_help = if you intended `{$param_name}` to be a const parameter, use `const {$param_name}: /* Type */` instead
hir_analysis_unused_generic_parameter_adt_help =
consider removing `{$param_name}`, referring to it in a field, or using a marker such as `{$phantom_data}`
hir_analysis_unused_generic_parameter_adt_no_phantom_data_help =
consider removing `{$param_name}` or referring to it in a field
hir_analysis_unused_generic_parameter_ty_alias_help =
consider removing `{$param_name}` or referring to it in the body of the type alias
hir_analysis_value_of_associated_struct_already_specified =
the value of the associated type `{$item_name}` in trait `{$def_path}` is already specified
.label = re-bound here

View file

@ -31,6 +31,7 @@
use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
use rustc_type_ir::fold::TypeFoldable;
use std::cell::LazyCell;
use std::ops::ControlFlow;
pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
@ -520,9 +521,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
}
}
DefKind::TyAlias => {
let pty_ty = tcx.type_of(def_id).instantiate_identity();
let generics = tcx.generics_of(def_id);
check_type_params_are_used(tcx, generics, pty_ty);
check_type_alias_type_params_are_used(tcx, def_id);
}
DefKind::ForeignMod => {
let it = tcx.hir().expect_item(def_id);
@ -1269,28 +1268,51 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
}
}
pub(super) fn check_type_params_are_used<'tcx>(
tcx: TyCtxt<'tcx>,
generics: &ty::Generics,
ty: Ty<'tcx>,
) {
debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
assert_eq!(generics.parent, None);
fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
if tcx.type_alias_is_lazy(def_id) {
// Since we compute the variances for lazy type aliases and already reject bivariant
// parameters as unused, we can and should skip this check for lazy type aliases.
return;
}
let generics = tcx.generics_of(def_id);
if generics.own_counts().types == 0 {
return;
}
let mut params_used = BitSet::new_empty(generics.params.len());
let ty = tcx.type_of(def_id).instantiate_identity();
if ty.references_error() {
// If there is already another error, do not emit
// an error for not using a type parameter.
// If there is already another error, do not emit an error for not using a type parameter.
assert!(tcx.dcx().has_errors().is_some());
return;
}
// Lazily calculated because it is only needed in case of an error.
let bounded_params = LazyCell::new(|| {
tcx.explicit_predicates_of(def_id)
.predicates
.iter()
.filter_map(|(predicate, span)| {
let bounded_ty = match predicate.kind().skip_binder() {
ty::ClauseKind::Trait(pred) => pred.trait_ref.self_ty(),
ty::ClauseKind::TypeOutlives(pred) => pred.0,
_ => return None,
};
if let ty::Param(param) = bounded_ty.kind() {
Some((param.index, span))
} else {
None
}
})
// FIXME: This assumes that elaborated `Sized` bounds come first (which does hold at the
// time of writing). This is a bit fragile since we later use the span to detect elaborated
// `Sized` bounds. If they came last for example, this would break `Trait + /*elab*/Sized`
// since it would overwrite the span of the user-written bound. This could be fixed by
// folding the spans with `Span::to` which requires a bit of effort I think.
.collect::<FxHashMap<_, _>>()
});
let mut params_used = BitSet::new_empty(generics.params.len());
for leaf in ty.walk() {
if let GenericArgKind::Type(leaf_ty) = leaf.unpack()
&& let ty::Param(param) = leaf_ty.kind()
@ -1305,15 +1327,24 @@ pub(super) fn check_type_params_are_used<'tcx>(
&& let ty::GenericParamDefKind::Type { .. } = param.kind
{
let span = tcx.def_span(param.def_id);
struct_span_code_err!(
tcx.dcx(),
let param_name = Ident::new(param.name, span);
// The corresponding predicates are post-`Sized`-elaboration. Therefore we
// * check for emptiness to detect lone user-written `?Sized` bounds
// * compare the param span to the pred span to detect lone user-written `Sized` bounds
let has_explicit_bounds = bounded_params.is_empty()
|| (*bounded_params).get(&param.index).is_some_and(|&&pred_sp| pred_sp != span);
let const_param_help = (!has_explicit_bounds).then_some(());
let mut diag = tcx.dcx().create_err(errors::UnusedGenericParameter {
span,
E0091,
"type parameter `{}` is unused",
param.name,
)
.with_span_label(span, "unused type parameter")
.emit();
param_name,
param_def_kind: tcx.def_descr(param.def_id),
help: errors::UnusedGenericParameterHelp::TyAlias { param_name },
const_param_help,
});
diag.code(E0091);
diag.emit();
}
}
}

View file

@ -1,11 +1,10 @@
use crate::autoderef::Autoderef;
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
use crate::errors;
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
};
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
use rustc_hir::lang_items::LangItem;
@ -21,7 +20,7 @@
};
use rustc_middle::ty::{GenericArgKind, GenericArgs};
use rustc_session::parse::feature_err;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::regions::InferCtxtRegionExt;
@ -1869,7 +1868,7 @@ fn check_variances_for_type_defn<'tcx>(
hir::ParamName::Error => {}
_ => {
let has_explicit_bounds = explicitly_bounded_params.contains(&parameter);
report_bivariance(tcx, hir_param, has_explicit_bounds);
report_bivariance(tcx, hir_param, has_explicit_bounds, item.kind);
}
}
}
@ -1879,30 +1878,38 @@ fn report_bivariance(
tcx: TyCtxt<'_>,
param: &rustc_hir::GenericParam<'_>,
has_explicit_bounds: bool,
item_kind: ItemKind<'_>,
) -> ErrorGuaranteed {
let span = param.span;
let param_name = param.name.ident().name;
let mut err = error_392(tcx, span, param_name);
let param_name = param.name.ident();
let suggested_marker_id = tcx.lang_items().phantom_data();
// Help is available only in presence of lang items.
let msg = if let Some(def_id) = suggested_marker_id {
format!(
"consider removing `{}`, referring to it in a field, or using a marker such as `{}`",
param_name,
tcx.def_path_str(def_id),
)
} else {
format!("consider removing `{param_name}` or referring to it in a field")
let help = match item_kind {
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
if let Some(def_id) = tcx.lang_items().phantom_data() {
errors::UnusedGenericParameterHelp::Adt {
param_name,
phantom_data: tcx.def_path_str(def_id),
}
} else {
errors::UnusedGenericParameterHelp::AdtNoPhantomData { param_name }
}
}
ItemKind::TyAlias(..) => errors::UnusedGenericParameterHelp::TyAlias { param_name },
item_kind => bug!("report_bivariance: unexpected item kind: {item_kind:?}"),
};
err.help(msg);
if matches!(param.kind, hir::GenericParamKind::Type { .. }) && !has_explicit_bounds {
err.help(format!(
"if you intended `{param_name}` to be a const parameter, use `const {param_name}: usize` instead"
));
}
err.emit()
let const_param_help =
matches!(param.kind, hir::GenericParamKind::Type { .. } if !has_explicit_bounds)
.then_some(());
let mut diag = tcx.dcx().create_err(errors::UnusedGenericParameter {
span: param.span,
param_name,
param_def_kind: tcx.def_descr(param.def_id.to_def_id()),
help,
const_param_help,
});
diag.code(E0392);
diag.emit()
}
impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
@ -1967,11 +1974,6 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), Error
res
}
fn error_392(tcx: TyCtxt<'_>, span: Span, param_name: Symbol) -> DiagnosticBuilder<'_> {
struct_span_code_err!(tcx.dcx(), span, E0392, "parameter `{param_name}` is never used")
.with_span_label(span, "unused parameter")
}
pub fn provide(providers: &mut Providers) {
*providers = Providers { check_mod_type_wf, check_well_formed, ..*providers };
}

View file

@ -1511,3 +1511,27 @@ pub struct NotSupportedDelegation<'a> {
#[label]
pub callee_span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_unused_generic_parameter)]
pub(crate) struct UnusedGenericParameter {
#[primary_span]
#[label]
pub span: Span,
pub param_name: Ident,
pub param_def_kind: &'static str,
#[subdiagnostic]
pub help: UnusedGenericParameterHelp,
#[help(hir_analysis_const_param_help)]
pub const_param_help: Option<()>,
}
#[derive(Subdiagnostic)]
pub(crate) enum UnusedGenericParameterHelp {
#[help(hir_analysis_unused_generic_parameter_adt_help)]
Adt { param_name: Ident, phantom_data: String },
#[help(hir_analysis_unused_generic_parameter_adt_no_phantom_data_help)]
AdtNoPhantomData { param_name: Ident },
#[help(hir_analysis_unused_generic_parameter_ty_alias_help)]
TyAlias { param_name: Ident },
}

View file

@ -10,14 +10,14 @@ error: expected identifier, found reserved identifier `_`
LL | fn bad_infer_fn<_>() {}
| ^ expected identifier, found reserved identifier
error[E0392]: parameter `_` is never used
error[E0392]: type parameter `_` is never used
--> $DIR/infer-arg-test.rs:7:17
|
LL | struct BadInfer<_>;
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `_` to be a const parameter, use `const _: usize` instead
= help: if you intended `_` to be a const parameter, use `const _: /* Type */` instead
error[E0107]: struct takes 2 generic arguments but 3 generic arguments were supplied
--> $DIR/infer-arg-test.rs:18:10

View file

@ -7,11 +7,11 @@ LL | _a: [u8; std::mem::size_of::<&'a mut u8>()]
= note: lifetime parameters may not be used in const expressions
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error[E0392]: parameter `'a` is never used
error[E0392]: lifetime parameter `'a` is never used
--> $DIR/issue-46511.rs:3:12
|
LL | struct Foo<'a>
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -7,14 +7,14 @@ LL | inner: [(); { [|_: &T| {}; 0].len() }],
= note: type parameters may not be used in const expressions
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/issue-67375.rs:5:12
|
LL | struct Bug<T> {
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -16,14 +16,14 @@ LL | let b = &*(&x as *const _ as *const S);
= note: type parameters may not be used in const expressions
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error[E0392]: parameter `S` is never used
error[E0392]: type parameter `S` is never used
--> $DIR/issue-67945-1.rs:7:12
|
LL | struct Bug<S> {
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
error: aborting due to 3 previous errors

View file

@ -7,14 +7,14 @@ LL | let x: Option<S> = None;
= note: type parameters may not be used in const expressions
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error[E0392]: parameter `S` is never used
error[E0392]: type parameter `S` is never used
--> $DIR/issue-67945-3.rs:9:12
|
LL | struct Bug<S> {
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -7,14 +7,14 @@ LL | let x: Option<Box<S>> = None;
= note: type parameters may not be used in const expressions
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error[E0392]: parameter `S` is never used
error[E0392]: type parameter `S` is never used
--> $DIR/issue-67945-4.rs:8:12
|
LL | struct Bug<S> {
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -1,4 +1,27 @@
#![crate_type="lib"]
struct Example<N>;
//~^ ERROR parameter
struct S<N>;
//~^ ERROR type parameter `N` is never used
//~| HELP consider removing `N`
//~| HELP if you intended `N` to be a const parameter
// Ensure that we don't emit the const param suggestion here:
struct T<N: Copy>;
//~^ ERROR type parameter `N` is never used
//~| HELP consider removing `N`
type A<N> = ();
//~^ ERROR type parameter `N` is never used
//~| HELP consider removing `N`
//~| HELP if you intended `N` to be a const parameter
// Ensure that we don't emit the const param suggestion here:
type B<N: Copy> = ();
//~^ ERROR type parameter `N` is never used
//~| HELP consider removing `N`
type C<N: Sized> = ();
//~^ ERROR type parameter `N` is never used
//~| HELP consider removing `N`
type D<N: ?Sized> = ();
//~^ ERROR type parameter `N` is never used
//~| HELP consider removing `N`

View file

@ -1,12 +1,54 @@
error[E0392]: parameter `N` is never used
--> $DIR/unused-type-param-suggestion.rs:3:16
error[E0392]: type parameter `N` is never used
--> $DIR/unused-type-param-suggestion.rs:3:10
|
LL | struct Example<N>;
| ^ unused parameter
LL | struct S<N>;
| ^ unused type parameter
|
= help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `N` to be a const parameter, use `const N: usize` instead
= help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead
error: aborting due to 1 previous error
error[E0392]: type parameter `N` is never used
--> $DIR/unused-type-param-suggestion.rs:9:10
|
LL | struct T<N: Copy>;
| ^ unused type parameter
|
= help: consider removing `N`, referring to it in a field, or using a marker such as `PhantomData`
For more information about this error, try `rustc --explain E0392`.
error[E0091]: type parameter `N` is never used
--> $DIR/unused-type-param-suggestion.rs:13:8
|
LL | type A<N> = ();
| ^ unused type parameter
|
= help: consider removing `N` or referring to it in the body of the type alias
= help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead
error[E0091]: type parameter `N` is never used
--> $DIR/unused-type-param-suggestion.rs:19:8
|
LL | type B<N: Copy> = ();
| ^ unused type parameter
|
= help: consider removing `N` or referring to it in the body of the type alias
error[E0091]: type parameter `N` is never used
--> $DIR/unused-type-param-suggestion.rs:22:8
|
LL | type C<N: Sized> = ();
| ^ unused type parameter
|
= help: consider removing `N` or referring to it in the body of the type alias
error[E0091]: type parameter `N` is never used
--> $DIR/unused-type-param-suggestion.rs:25:8
|
LL | type D<N: ?Sized> = ();
| ^ unused type parameter
|
= help: consider removing `N` or referring to it in the body of the type alias
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0091, E0392.
For more information about an error, try `rustc --explain E0091`.

View file

@ -6,14 +6,14 @@ LL | Some = std::mem::size_of::<T>(),
|
= note: type parameters may not be used in enum discriminant values
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/issue-70453-generics-in-discr-ice.rs:7:20
|
LL | enum MyWeirdOption<T> {
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -6,14 +6,14 @@ LL | let x: S = 0;
|
= note: type parameters may not be used in enum discriminant values
error[E0392]: parameter `S` is never used
error[E0392]: type parameter `S` is never used
--> $DIR/issue-67945-1.rs:1:10
|
LL | enum Bug<S> {
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -6,14 +6,14 @@ LL | Var = type_ascribe!(0, S),
|
= note: type parameters may not be used in enum discriminant values
error[E0392]: parameter `S` is never used
error[E0392]: type parameter `S` is never used
--> $DIR/issue-67945-2.rs:3:10
|
LL | enum Bug<S> {
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `S` to be a const parameter, use `const S: usize` instead
= help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -1,14 +1,20 @@
error[E0091]: type parameter `T` is unused
error[E0091]: type parameter `T` is never used
--> $DIR/E0091.rs:1:10
|
LL | type Foo<T> = u32;
| ^ unused type parameter
|
= help: consider removing `T` or referring to it in the body of the type alias
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error[E0091]: type parameter `B` is unused
error[E0091]: type parameter `B` is never used
--> $DIR/E0091.rs:2:14
|
LL | type Foo2<A, B> = Box<A>;
| ^ unused type parameter
|
= help: consider removing `B` or referring to it in the body of the type alias
= help: if you intended `B` to be a const parameter, use `const B: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -1,11 +1,11 @@
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/E0392.rs:1:10
|
LL | enum Foo<T> { Bar }
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error: aborting due to 1 previous error

View file

@ -6,14 +6,14 @@ LL | fn foo<T>() {
LL | static a: Bar<T> = Bar::What;
| ^ use of generic parameter from outer item
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/inner-static-type-parameter.rs:3:10
|
LL | enum Bar<T> { What }
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -1,8 +1,8 @@
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/issue-17904-2.rs:4:12
|
LL | struct Foo<T> where T: Copy;
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -1,3 +1,3 @@
trait Tr {}
type Huh<T> where T: Tr = isize; //~ ERROR type parameter `T` is unused
type Huh<T> where T: Tr = isize; //~ ERROR type parameter `T` is never used
fn main() {}

View file

@ -1,8 +1,10 @@
error[E0091]: type parameter `T` is unused
error[E0091]: type parameter `T` is never used
--> $DIR/issue-17994.rs:2:10
|
LL | type Huh<T> where T: Tr = isize;
| ^ unused type parameter
|
= help: consider removing `T` or referring to it in the body of the type alias
error: aborting due to 1 previous error

View file

@ -1,11 +1,11 @@
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/issue-20413.rs:6:15
|
LL | struct NoData<T>;
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>: Foo`
--> $DIR/issue-20413.rs:9:36

View file

@ -1,5 +1,5 @@
type Foo<
Unused //~ ERROR type parameter `Unused` is unused
Unused //~ ERROR type parameter `Unused` is never used
> = u8;
fn main() {

View file

@ -1,8 +1,11 @@
error[E0091]: type parameter `Unused` is unused
error[E0091]: type parameter `Unused` is never used
--> $DIR/issue-30236.rs:2:5
|
LL | Unused
| ^^^^^^ unused type parameter
|
= help: consider removing `Unused` or referring to it in the body of the type alias
= help: if you intended `Unused` to be a const parameter, use `const Unused: /* Type */` instead
error: aborting due to 1 previous error

View file

@ -4,11 +4,11 @@ error[E0308]: mismatched types
LL | X = Trait::Number,
| ^^^^^^^^^^^^^ expected `isize`, found `i32`
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/issue-31910.rs:1:11
|
LL | enum Enum<T: Trait> {
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -45,14 +45,14 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
LL | fn foo(_: T) where Self: Sized {}
| +++++++++++++++++
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/issue-34373.rs:7:16
|
LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unused parameter
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error: aborting due to 3 previous errors

View file

@ -1,19 +1,19 @@
error[E0392]: parameter `'a` is never used
error[E0392]: lifetime parameter `'a` is never used
--> $DIR/issue-36299.rs:1:12
|
LL | struct Foo<'a, A> {}
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
error[E0392]: parameter `A` is never used
error[E0392]: type parameter `A` is never used
--> $DIR/issue-36299.rs:1:16
|
LL | struct Foo<'a, A> {}
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `A`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `A` to be a const parameter, use `const A: usize` instead
= help: if you intended `A` to be a const parameter, use `const A: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -15,11 +15,11 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
LL | struct Foo<T: ?Hash> {}
| ^^^^^
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/issue-37534.rs:1:12
|
LL | struct Foo<T: ?Hash> {}
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -50,23 +50,23 @@ LL |
LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
| - this function has 0 generic arguments
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/lang-item-generic-requirements.rs:24:22
|
LL | struct MyPhantomData<T, U>;
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T` or referring to it in a field
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error[E0392]: parameter `U` is never used
error[E0392]: type parameter `U` is never used
--> $DIR/lang-item-generic-requirements.rs:24:25
|
LL | struct MyPhantomData<T, U>;
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `U` or referring to it in a field
= help: if you intended `U` to be a const parameter, use `const U: usize` instead
= help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead
error[E0369]: cannot add `{integer}` to `{integer}`
--> $DIR/lang-item-generic-requirements.rs:44:7

View file

@ -0,0 +1,22 @@
// Check that we reject bivariant generic parameters as unused.
// Furthermore, check that we only emit a single diagnostic for unused type parameters:
// Previously, we would emit *two* errors, namely E0392 and E0091.
#![feature(lazy_type_alias)]
#![allow(incomplete_features)]
type A<'a> = ();
//~^ ERROR lifetime parameter `'a` is never used
//~| HELP consider removing `'a`
type B<T> = ();
//~^ ERROR type parameter `T` is never used
//~| HELP consider removing `T`
//~| HELP if you intended `T` to be a const parameter
// Check that we don't emit the const param help message here:
type C<T: Copy> = ();
//~^ ERROR type parameter `T` is never used
//~| HELP consider removing `T`
fn main() {}

View file

@ -0,0 +1,28 @@
error[E0392]: lifetime parameter `'a` is never used
--> $DIR/unused-generic-parameters.rs:8:8
|
LL | type A<'a> = ();
| ^^ unused lifetime parameter
|
= help: consider removing `'a` or referring to it in the body of the type alias
error[E0392]: type parameter `T` is never used
--> $DIR/unused-generic-parameters.rs:12:8
|
LL | type B<T> = ();
| ^ unused type parameter
|
= help: consider removing `T` or referring to it in the body of the type alias
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error[E0392]: type parameter `T` is never used
--> $DIR/unused-generic-parameters.rs:18:8
|
LL | type C<T: Copy> = ();
| ^ unused type parameter
|
= help: consider removing `T` or referring to it in the body of the type alias
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0392`.

View file

@ -13,19 +13,19 @@ error: generic `Self` types are currently not permitted in anonymous constants
LL | array: [(); size_of::<&Self>()],
| ^^^^
error[E0392]: parameter `'s` is never used
error[E0392]: lifetime parameter `'s` is never used
--> $DIR/issue-64173-unused-lifetimes.rs:3:12
|
LL | struct Foo<'s> {
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'s`, referring to it in a field, or using a marker such as `PhantomData`
error[E0392]: parameter `'a` is never used
error[E0392]: lifetime parameter `'a` is never used
--> $DIR/issue-64173-unused-lifetimes.rs:15:12
|
LL | struct Bar<'a> {
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -13,8 +13,8 @@ fn semantics() {
//~| ERROR free type alias without body
type E<_T>: Ord = u8;
//~^ ERROR bounds on `type`s in this context have no effect
//~| ERROR type parameter `_T` is unused
//~| ERROR type parameter `_T` is never used
type F<_T>: Ord where 'static: 'static = u8;
//~^ ERROR bounds on `type`s in this context have no effect
//~| ERROR type parameter `_T` is unused
//~| ERROR type parameter `_T` is never used
}

View file

@ -50,17 +50,23 @@ error: bounds on `type`s in this context have no effect
LL | type F<_T>: Ord where 'static: 'static = u8;
| ^^^
error[E0091]: type parameter `_T` is unused
error[E0091]: type parameter `_T` is never used
--> $DIR/item-free-type-bounds-semantic-fail.rs:14:12
|
LL | type E<_T>: Ord = u8;
| ^^ unused type parameter
|
= help: consider removing `_T` or referring to it in the body of the type alias
= help: if you intended `_T` to be a const parameter, use `const _T: /* Type */` instead
error[E0091]: type parameter `_T` is unused
error[E0091]: type parameter `_T` is never used
--> $DIR/item-free-type-bounds-semantic-fail.rs:17:12
|
LL | type F<_T>: Ord where 'static: 'static = u8;
| ^^ unused type parameter
|
= help: consider removing `_T` or referring to it in the body of the type alias
= help: if you intended `_T` to be a const parameter, use `const _T: /* Type */` instead
error: aborting due to 10 previous errors

View file

@ -21,11 +21,11 @@ note: but lifetime parameter must outlive the lifetime `'a` as defined here
LL | struct Foo<'a,'b,'c> {
| ^^
error[E0392]: parameter `'c` is never used
error[E0392]: lifetime parameter `'c` is never used
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:18
|
LL | struct Foo<'a,'b,'c> {
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -272,11 +272,11 @@ LL | type Type<T: ~const Trait> = ();
= help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/tilde-const-invalid-places.rs:11:19
|
LL | struct UnitStruct<T: ~const Trait>;
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -72,11 +72,11 @@ note: unit struct `foo::Self` exists but is inaccessible
LL | struct Self;
| ^^^^^^^^^^^^ not accessible
error[E0392]: parameter `'Self` is never used
error[E0392]: lifetime parameter `'Self` is never used
--> $DIR/self_type_keyword.rs:6:12
|
LL | struct Bar<'Self>;
| ^^^^^ unused parameter
| ^^^^^ unused lifetime parameter
|
= help: consider removing `'Self`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -14,14 +14,14 @@ help: add missing generic argument
LL | fn foo(c: Quux<T>) { assert!((false)); }
| +++
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/tag-type-args.rs:1:11
|
LL | enum Quux<T> { Bar }
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error: aborting due to 2 previous errors

View file

@ -1,16 +1,16 @@
error[E0392]: parameter `'a` is never used
error[E0392]: lifetime parameter `'a` is never used
--> $DIR/variance-regions-unused-direct.rs:5:18
|
LL | struct Bivariant<'a>;
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
error[E0392]: parameter `'d` is never used
error[E0392]: lifetime parameter `'d` is never used
--> $DIR/variance-regions-unused-direct.rs:7:19
|
LL | struct Struct<'a, 'd> {
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'d`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -21,19 +21,19 @@ LL | enum Bar<'a> {
LL ~ Bar1(Box<Foo<'a>>)
|
error[E0392]: parameter `'a` is never used
error[E0392]: lifetime parameter `'a` is never used
--> $DIR/variance-regions-unused-indirect.rs:3:10
|
LL | enum Foo<'a> {
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
error[E0392]: parameter `'a` is never used
error[E0392]: lifetime parameter `'a` is never used
--> $DIR/variance-regions-unused-indirect.rs:8:10
|
LL | enum Bar<'a> {
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -1,16 +1,16 @@
error[E0392]: parameter `'a` is never used
error[E0392]: lifetime parameter `'a` is never used
--> $DIR/variance-unused-region-param.rs:3:19
|
LL | struct SomeStruct<'a> { x: u32 }
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
error[E0392]: parameter `'a` is never used
error[E0392]: lifetime parameter `'a` is never used
--> $DIR/variance-unused-region-param.rs:4:15
|
LL | enum SomeEnum<'a> { Nothing }
| ^^ unused parameter
| ^^ unused lifetime parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`

View file

@ -1,51 +1,51 @@
error[E0392]: parameter `A` is never used
error[E0392]: type parameter `A` is never used
--> $DIR/variance-unused-type-param.rs:6:19
|
LL | struct SomeStruct<A> { x: u32 }
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `A`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `A` to be a const parameter, use `const A: usize` instead
= help: if you intended `A` to be a const parameter, use `const A: /* Type */` instead
error[E0392]: parameter `A` is never used
error[E0392]: type parameter `A` is never used
--> $DIR/variance-unused-type-param.rs:9:15
|
LL | enum SomeEnum<A> { Nothing }
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `A`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `A` to be a const parameter, use `const A: usize` instead
= help: if you intended `A` to be a const parameter, use `const A: /* Type */` instead
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/variance-unused-type-param.rs:13:15
|
LL | enum ListCell<T> {
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/variance-unused-type-param.rs:19:19
|
LL | struct WithBounds<T: Sized> {}
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/variance-unused-type-param.rs:22:24
|
LL | struct WithWhereBounds<T> where T: Sized {}
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
error[E0392]: parameter `T` is never used
error[E0392]: type parameter `T` is never used
--> $DIR/variance-unused-type-param.rs:25:27
|
LL | struct WithOutlivesBounds<T: 'static> {}
| ^ unused parameter
| ^ unused type parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`