Skip to content

Commit

Permalink
Rollup merge of rust-lang#93400 - ChayimFriedman2:dont-suggest-using-…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
Dylan-DPC authored Feb 26, 2022
2 parents 12b71ed + 4520045 commit 9fe927a
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 7 deletions.
36 changes: 32 additions & 4 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode,

use std::convert::TryInto;
use std::iter;
use std::lazy::Lazy;
use std::ops::ControlFlow;

/// Helper type of a temporary returned by `.for_item(...)`.
Expand Down Expand Up @@ -1720,8 +1721,29 @@ fn check_variances_for_type_defn<'tcx>(

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() {
if constrained_parameters.contains(&Parameter(index as u32)) {
let parameter = Parameter(index as u32);

if constrained_parameters.contains(&parameter) {
continue;
}

Expand All @@ -1730,13 +1752,19 @@ fn check_variances_for_type_defn<'tcx>(
match param.name {
hir::ParamName::Error => {}
_ => {
report_bivariance(tcx, param);
let has_explicit_bounds =
!param.bounds.is_empty() || explicitly_bounded_params.contains(&parameter);
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 param_name = param.name.ident().name;
let mut err = error_392(tcx, span, param_name);
Expand All @@ -1754,7 +1782,7 @@ fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) -> Er
};
err.help(&msg);

if matches!(param.kind, rustc_hir::GenericParamKind::Type { .. }) {
if matches!(param.kind, hir::GenericParamKind::Type { .. }) && !has_explicit_bounds {
err.help(&format!(
"if you intended `{0}` to be a const parameter, use `const {0}: usize` instead",
param_name
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ This API is completely unstable and subject to change.
#![feature(slice_partition_dedup)]
#![feature(control_flow_enum)]
#![feature(hash_drain_filter)]
#![feature(once_cell)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

Expand Down
1 change: 0 additions & 1 deletion src/test/ui/issues/issue-17904-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ LL | struct Foo<T> where T: Copy;
| ^ unused 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

error: aborting due to previous error

Expand Down
1 change: 0 additions & 1 deletion src/test/ui/issues/issue-37534.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ LL | struct Foo<T: ?Hash> { }
| ^ unused 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

error: aborting due to 2 previous errors; 1 warning emitted

Expand Down
9 changes: 9 additions & 0 deletions src/test/ui/variance/variance-unused-type-param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,13 @@ enum ListCell<T> {
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() {}
26 changes: 25 additions & 1 deletion src/test/ui/variance/variance-unused-type-param.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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: 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`.

0 comments on commit 9fe927a

Please sign in to comment.