Rollup merge of #93400 - ChayimFriedman2:dont-suggest-using-const-with-bounds-unused-generic-param, r=jackh726
Do not suggest using a const parameter when there are bounds on an unused type parameter The user wrote the bound, so it's obvious they want a type.
This commit is contained in:
commit
be9b99b0d0
@ -31,6 +31,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode,
|
|||||||
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
use std::lazy::Lazy;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
/// Helper type of a temporary returned by `.for_item(...)`.
|
/// Helper type of a temporary returned by `.for_item(...)`.
|
||||||
@ -1720,8 +1721,29 @@ fn check_variances_for_type_defn<'tcx>(
|
|||||||
|
|
||||||
identify_constrained_generic_params(tcx, ty_predicates, None, &mut constrained_parameters);
|
identify_constrained_generic_params(tcx, ty_predicates, None, &mut constrained_parameters);
|
||||||
|
|
||||||
|
// Lazily calculated because it is only needed in case of an error.
|
||||||
|
let explicitly_bounded_params = Lazy::new(|| {
|
||||||
|
let icx = crate::collect::ItemCtxt::new(tcx, item.def_id.to_def_id());
|
||||||
|
hir_generics
|
||||||
|
.where_clause
|
||||||
|
.predicates
|
||||||
|
.iter()
|
||||||
|
.filter_map(|predicate| match predicate {
|
||||||
|
hir::WherePredicate::BoundPredicate(predicate) => {
|
||||||
|
match icx.to_ty(predicate.bounded_ty).kind() {
|
||||||
|
ty::Param(data) => Some(Parameter(data.index)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<FxHashSet<_>>()
|
||||||
|
});
|
||||||
|
|
||||||
for (index, _) in variances.iter().enumerate() {
|
for (index, _) in variances.iter().enumerate() {
|
||||||
if constrained_parameters.contains(&Parameter(index as u32)) {
|
let parameter = Parameter(index as u32);
|
||||||
|
|
||||||
|
if constrained_parameters.contains(¶meter) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1730,13 +1752,19 @@ fn check_variances_for_type_defn<'tcx>(
|
|||||||
match param.name {
|
match param.name {
|
||||||
hir::ParamName::Error => {}
|
hir::ParamName::Error => {}
|
||||||
_ => {
|
_ => {
|
||||||
report_bivariance(tcx, param);
|
let has_explicit_bounds =
|
||||||
|
!param.bounds.is_empty() || explicitly_bounded_params.contains(¶meter);
|
||||||
|
report_bivariance(tcx, param, has_explicit_bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) -> ErrorReported {
|
fn report_bivariance(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
param: &rustc_hir::GenericParam<'_>,
|
||||||
|
has_explicit_bounds: bool,
|
||||||
|
) -> ErrorReported {
|
||||||
let span = param.span;
|
let span = param.span;
|
||||||
let param_name = param.name.ident().name;
|
let param_name = param.name.ident().name;
|
||||||
let mut err = error_392(tcx, span, param_name);
|
let mut err = error_392(tcx, span, param_name);
|
||||||
@ -1754,7 +1782,7 @@ fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) -> Er
|
|||||||
};
|
};
|
||||||
err.help(&msg);
|
err.help(&msg);
|
||||||
|
|
||||||
if matches!(param.kind, rustc_hir::GenericParamKind::Type { .. }) {
|
if matches!(param.kind, hir::GenericParamKind::Type { .. }) && !has_explicit_bounds {
|
||||||
err.help(&format!(
|
err.help(&format!(
|
||||||
"if you intended `{0}` to be a const parameter, use `const {0}: usize` instead",
|
"if you intended `{0}` to be a const parameter, use `const {0}: usize` instead",
|
||||||
param_name
|
param_name
|
||||||
|
@ -68,6 +68,7 @@ This API is completely unstable and subject to change.
|
|||||||
#![feature(slice_partition_dedup)]
|
#![feature(slice_partition_dedup)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![feature(hash_drain_filter)]
|
#![feature(hash_drain_filter)]
|
||||||
|
#![feature(once_cell)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
#![allow(rustc::potential_query_instability)]
|
#![allow(rustc::potential_query_instability)]
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ LL | struct Foo<T> where T: Copy;
|
|||||||
| ^ unused parameter
|
| ^ unused parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= 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
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ LL | struct Foo<T: ?Hash> { }
|
|||||||
| ^ unused parameter
|
| ^ unused parameter
|
||||||
|
|
|
|
||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= 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
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 1 warning emitted
|
error: aborting due to 2 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
@ -16,4 +16,13 @@ enum ListCell<T> {
|
|||||||
Nil
|
Nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct WithBounds<T: Sized> {}
|
||||||
|
//~^ ERROR parameter `T` is never used
|
||||||
|
|
||||||
|
struct WithWhereBounds<T> where T: Sized {}
|
||||||
|
//~^ ERROR parameter `T` is never used
|
||||||
|
|
||||||
|
struct WithOutlivesBounds<T: 'static> {}
|
||||||
|
//~^ ERROR parameter `T` is never used
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -25,6 +25,30 @@ LL | enum ListCell<T> {
|
|||||||
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
= 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: usize` instead
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0392]: parameter `T` is never used
|
||||||
|
--> $DIR/variance-unused-type-param.rs:19:19
|
||||||
|
|
|
||||||
|
LL | struct WithBounds<T: Sized> {}
|
||||||
|
| ^ unused 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
|
||||||
|
--> $DIR/variance-unused-type-param.rs:22:24
|
||||||
|
|
|
||||||
|
LL | struct WithWhereBounds<T> where T: Sized {}
|
||||||
|
| ^ unused 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
|
||||||
|
--> $DIR/variance-unused-type-param.rs:25:27
|
||||||
|
|
|
||||||
|
LL | struct WithOutlivesBounds<T: 'static> {}
|
||||||
|
| ^ unused parameter
|
||||||
|
|
|
||||||
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0392`.
|
For more information about this error, try `rustc --explain E0392`.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user