Handle empty where-clause better
This commit is contained in:
parent
8506b7d4e0
commit
9c47afe9fa
23 changed files with 78 additions and 59 deletions
|
@ -1377,7 +1377,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
let mut params: SmallVec<[hir::GenericParam<'hir>; 4]> =
|
let mut params: SmallVec<[hir::GenericParam<'hir>; 4]> =
|
||||||
self.lower_generic_params_mut(&generics.params).collect();
|
self.lower_generic_params_mut(&generics.params).collect();
|
||||||
let has_where_clause = !generics.where_clause.predicates.is_empty();
|
let has_where_clause_predicates = !generics.where_clause.predicates.is_empty();
|
||||||
|
let has_where_clause_token = generics.where_clause.has_where_token;
|
||||||
let where_clause_span = self.lower_span(generics.where_clause.span);
|
let where_clause_span = self.lower_span(generics.where_clause.span);
|
||||||
let span = self.lower_span(generics.span);
|
let span = self.lower_span(generics.span);
|
||||||
let res = f(self);
|
let res = f(self);
|
||||||
|
@ -1395,7 +1396,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let lowered_generics = self.arena.alloc(hir::Generics {
|
let lowered_generics = self.arena.alloc(hir::Generics {
|
||||||
params: self.arena.alloc_from_iter(params),
|
params: self.arena.alloc_from_iter(params),
|
||||||
predicates: self.arena.alloc_from_iter(predicates),
|
predicates: self.arena.alloc_from_iter(predicates),
|
||||||
has_where_clause,
|
has_where_clause_predicates,
|
||||||
|
has_where_clause_token,
|
||||||
where_clause_span,
|
where_clause_span,
|
||||||
span,
|
span,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1315,7 +1315,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
generics: self.arena.alloc(hir::Generics {
|
generics: self.arena.alloc(hir::Generics {
|
||||||
params: lifetime_defs,
|
params: lifetime_defs,
|
||||||
predicates: &[],
|
predicates: &[],
|
||||||
has_where_clause: false,
|
has_where_clause_predicates: false,
|
||||||
|
has_where_clause_token: false,
|
||||||
where_clause_span: lctx.lower_span(span),
|
where_clause_span: lctx.lower_span(span),
|
||||||
span: lctx.lower_span(span),
|
span: lctx.lower_span(span),
|
||||||
}),
|
}),
|
||||||
|
@ -1637,7 +1638,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
generics: this.arena.alloc(hir::Generics {
|
generics: this.arena.alloc(hir::Generics {
|
||||||
params: generic_params,
|
params: generic_params,
|
||||||
predicates: &[],
|
predicates: &[],
|
||||||
has_where_clause: false,
|
has_where_clause_predicates: false,
|
||||||
|
has_where_clause_token: false,
|
||||||
where_clause_span: this.lower_span(span),
|
where_clause_span: this.lower_span(span),
|
||||||
span: this.lower_span(span),
|
span: this.lower_span(span),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -535,7 +535,8 @@ pub struct GenericParamCount {
|
||||||
pub struct Generics<'hir> {
|
pub struct Generics<'hir> {
|
||||||
pub params: &'hir [GenericParam<'hir>],
|
pub params: &'hir [GenericParam<'hir>],
|
||||||
pub predicates: &'hir [WherePredicate<'hir>],
|
pub predicates: &'hir [WherePredicate<'hir>],
|
||||||
pub has_where_clause: bool,
|
pub has_where_clause_predicates: bool,
|
||||||
|
pub has_where_clause_token: bool,
|
||||||
pub where_clause_span: Span,
|
pub where_clause_span: Span,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
@ -545,7 +546,8 @@ impl<'hir> Generics<'hir> {
|
||||||
const NOPE: Generics<'_> = Generics {
|
const NOPE: Generics<'_> = Generics {
|
||||||
params: &[],
|
params: &[],
|
||||||
predicates: &[],
|
predicates: &[],
|
||||||
has_where_clause: false,
|
has_where_clause_predicates: false,
|
||||||
|
has_where_clause_token: false,
|
||||||
where_clause_span: DUMMY_SP,
|
where_clause_span: DUMMY_SP,
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
};
|
};
|
||||||
|
@ -585,17 +587,11 @@ impl<'hir> Generics<'hir> {
|
||||||
if self.predicates.is_empty() { None } else { Some(self.where_clause_span) }
|
if self.predicates.is_empty() { None } else { Some(self.where_clause_span) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `where_span` under normal circumstances points at either the predicates or the empty
|
|
||||||
/// space where the `where` clause should be. Only of use for diagnostic suggestions.
|
|
||||||
pub fn span_for_predicates_or_empty_place(&self) -> Span {
|
|
||||||
self.where_clause_span
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `Span` where further predicates would be suggested, accounting for trailing commas, like
|
/// `Span` where further predicates would be suggested, accounting for trailing commas, like
|
||||||
/// in `fn foo<T>(t: T) where T: Foo,` so we don't suggest two trailing commas.
|
/// in `fn foo<T>(t: T) where T: Foo,` so we don't suggest two trailing commas.
|
||||||
pub fn tail_span_for_predicate_suggestion(&self) -> Span {
|
pub fn tail_span_for_predicate_suggestion(&self) -> Span {
|
||||||
let end = self.span_for_predicates_or_empty_place().shrink_to_hi();
|
let end = self.where_clause_span.shrink_to_hi();
|
||||||
if self.has_where_clause {
|
if self.has_where_clause_predicates {
|
||||||
self.predicates
|
self.predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| p.in_where_clause())
|
.filter(|p| p.in_where_clause())
|
||||||
|
@ -608,6 +604,16 @@ impl<'hir> Generics<'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_where_or_trailing_comma(&self) -> &'static str {
|
||||||
|
if self.has_where_clause_predicates {
|
||||||
|
","
|
||||||
|
} else if self.has_where_clause_token {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
" where"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn bounds_for_param(
|
pub fn bounds_for_param(
|
||||||
&self,
|
&self,
|
||||||
param_def_id: LocalDefId,
|
param_def_id: LocalDefId,
|
||||||
|
|
|
@ -2511,7 +2511,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
let pred = format!("{}: {}", bound_kind, sub);
|
let pred = format!("{}: {}", bound_kind, sub);
|
||||||
let suggestion = format!(
|
let suggestion = format!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
if !generics.predicates.is_empty() { "," } else { " where" },
|
generics.add_where_or_trailing_comma(),
|
||||||
pred,
|
pred,
|
||||||
);
|
);
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
|
|
|
@ -367,17 +367,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if !clauses.is_empty() {
|
if !clauses.is_empty() {
|
||||||
let where_clause_span = self
|
let generics = self.tcx.hir().get_generics(impl_item_def_id).unwrap();
|
||||||
.tcx
|
let where_clause_span = generics.tail_span_for_predicate_suggestion();
|
||||||
.hir()
|
|
||||||
.get_generics(impl_item_def_id)
|
|
||||||
.unwrap()
|
|
||||||
.where_clause_span
|
|
||||||
.shrink_to_hi();
|
|
||||||
|
|
||||||
let suggestion = format!(
|
let suggestion = format!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
if !impl_predicates.is_empty() { "," } else { " where" },
|
generics.add_where_or_trailing_comma(),
|
||||||
clauses.join(", "),
|
clauses.join(", "),
|
||||||
);
|
);
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
|
|
|
@ -2293,7 +2293,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
|
||||||
|
|
||||||
// If all predicates are inferable, drop the entire clause
|
// If all predicates are inferable, drop the entire clause
|
||||||
// (including the `where`)
|
// (including the `where`)
|
||||||
if hir_generics.has_where_clause && dropped_predicate_count == num_predicates {
|
if hir_generics.has_where_clause_predicates && dropped_predicate_count == num_predicates
|
||||||
|
{
|
||||||
let where_span = hir_generics
|
let where_span = hir_generics
|
||||||
.where_clause_span()
|
.where_clause_span()
|
||||||
.expect("span of (nonempty) where clause should exist");
|
.expect("span of (nonempty) where clause should exist");
|
||||||
|
|
|
@ -92,19 +92,14 @@ pub fn suggest_arbitrary_trait_bound(
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
// Suggest a where clause bound for a non-type parameter.
|
// Suggest a where clause bound for a non-type parameter.
|
||||||
let (action, prefix) = if generics.has_where_clause {
|
|
||||||
("extending the", ", ")
|
|
||||||
} else {
|
|
||||||
("introducing a", " where ")
|
|
||||||
};
|
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
generics.tail_span_for_predicate_suggestion(),
|
generics.tail_span_for_predicate_suggestion(),
|
||||||
&format!(
|
&format!(
|
||||||
"consider {} `where` bound, but there might be an alternative better way to express \
|
"consider {} `where` clause, but there might be an alternative better way to express \
|
||||||
this requirement",
|
this requirement",
|
||||||
action,
|
if generics.has_where_clause_token { "extending the" } else { "introducing a" },
|
||||||
),
|
),
|
||||||
format!("{}{}: {}", prefix, param_name, constraint),
|
format!("{} {}: {}", generics.add_where_or_trailing_comma(), param_name, constraint),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
true
|
true
|
||||||
|
@ -257,7 +252,7 @@ pub fn suggest_constraining_type_params<'a>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if generics.has_where_clause {
|
if generics.has_where_clause_predicates {
|
||||||
// This part is a bit tricky, because using the `where` clause user can
|
// This part is a bit tricky, because using the `where` clause user can
|
||||||
// provide zero, one or many bounds for the same type parameter, so we
|
// provide zero, one or many bounds for the same type parameter, so we
|
||||||
// have following cases to consider:
|
// have following cases to consider:
|
||||||
|
|
|
@ -324,7 +324,7 @@ pub trait InferCtxtExt<'tcx> {
|
||||||
fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
|
fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
|
||||||
(
|
(
|
||||||
generics.tail_span_for_predicate_suggestion(),
|
generics.tail_span_for_predicate_suggestion(),
|
||||||
format!("{} {}", if generics.has_where_clause { "," } else { " where" }, pred,),
|
format!("{} {}", generics.add_where_or_trailing_comma(), pred),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,15 +339,16 @@ fn suggest_restriction<'tcx>(
|
||||||
fn_sig: Option<&hir::FnSig<'_>>,
|
fn_sig: Option<&hir::FnSig<'_>>,
|
||||||
projection: Option<&ty::ProjectionTy<'_>>,
|
projection: Option<&ty::ProjectionTy<'_>>,
|
||||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||||
super_traits: Option<(&Ident, &hir::GenericBounds<'_>)>,
|
|
||||||
) {
|
|
||||||
// When we are dealing with a trait, `super_traits` will be `Some`:
|
// When we are dealing with a trait, `super_traits` will be `Some`:
|
||||||
// Given `trait T: A + B + C {}`
|
// Given `trait T: A + B + C {}`
|
||||||
// - ^^^^^^^^^ GenericBounds
|
// - ^^^^^^^^^ GenericBounds
|
||||||
// |
|
// |
|
||||||
// &Ident
|
// &Ident
|
||||||
let span = generics.span_for_predicates_or_empty_place();
|
super_traits: Option<(&Ident, &hir::GenericBounds<'_>)>,
|
||||||
if span.from_expansion() || span.desugaring_kind().is_some() {
|
) {
|
||||||
|
if generics.where_clause_span.from_expansion()
|
||||||
|
|| generics.where_clause_span.desugaring_kind().is_some()
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Given `fn foo(t: impl Trait)` where `Trait` requires assoc type `A`...
|
// Given `fn foo(t: impl Trait)` where `Trait` requires assoc type `A`...
|
||||||
|
|
|
@ -538,10 +538,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
|
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
|
||||||
if let Some(g) = kind.generics() {
|
if let Some(g) = kind.generics() {
|
||||||
let key = match g.predicates {
|
let key = (
|
||||||
[.., pred] => (pred.span().shrink_to_hi(), false),
|
g.tail_span_for_predicate_suggestion(),
|
||||||
[] => (g.span_for_predicates_or_empty_place(), true),
|
g.add_where_or_trailing_comma(),
|
||||||
};
|
);
|
||||||
type_params
|
type_params
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(FxHashSet::default)
|
.or_insert_with(FxHashSet::default)
|
||||||
|
@ -805,7 +805,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.collect::<Vec<(usize, String)>>();
|
.collect::<Vec<(usize, String)>>();
|
||||||
|
|
||||||
for ((span, empty_where), obligations) in type_params.into_iter() {
|
for ((span, add_where_or_comma), obligations) in type_params.into_iter() {
|
||||||
restrict_type_params = true;
|
restrict_type_params = true;
|
||||||
// #74886: Sort here so that the output is always the same.
|
// #74886: Sort here so that the output is always the same.
|
||||||
let mut obligations = obligations.into_iter().collect::<Vec<_>>();
|
let mut obligations = obligations.into_iter().collect::<Vec<_>>();
|
||||||
|
@ -819,7 +819,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
),
|
),
|
||||||
format!(
|
format!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
if empty_where { " where" } else { "," },
|
add_where_or_comma,
|
||||||
obligations.join(", ")
|
obligations.join(", ")
|
||||||
),
|
),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
|
|
|
@ -421,7 +421,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
||||||
|
|
||||||
let suggestion = format!(
|
let suggestion = format!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
if !gat_item_hir.generics.predicates.is_empty() { "," } else { " where" },
|
gat_item_hir.generics.add_where_or_trailing_comma(),
|
||||||
unsatisfied_bounds.join(", "),
|
unsatisfied_bounds.join(", "),
|
||||||
);
|
);
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | a.iter().map(|a| a*a)
|
||||||
| |
|
| |
|
||||||
| &T
|
| &T
|
||||||
|
|
|
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> where &T: Mul<&T> {
|
LL | fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> where &T: Mul<&T> {
|
||||||
| +++++++++++++++++
|
| +++++++++++++++++
|
||||||
|
|
|
@ -2,6 +2,11 @@ fn foo<T: PartialEq>(a: &T, b: T) {
|
||||||
a == b; //~ ERROR E0277
|
a == b; //~ ERROR E0277
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foo2<T: PartialEq>(a: &T, b: T) where {
|
||||||
|
a == b; //~ ERROR E0277
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
foo(&1, 1);
|
foo(&1, 1);
|
||||||
|
foo2(&1, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,23 @@ LL | a == b;
|
||||||
| ^^ no implementation for `&T == T`
|
| ^^ no implementation for `&T == T`
|
||||||
|
|
|
|
||||||
= help: the trait `PartialEq<T>` is not implemented for `&T`
|
= help: the trait `PartialEq<T>` is not implemented for `&T`
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | fn foo<T: PartialEq>(a: &T, b: T) where &T: PartialEq<T> {
|
LL | fn foo<T: PartialEq>(a: &T, b: T) where &T: PartialEq<T> {
|
||||||
| ++++++++++++++++++++++
|
| ++++++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0277]: can't compare `&T` with `T`
|
||||||
|
--> $DIR/partialeq_help.rs:6:7
|
||||||
|
|
|
||||||
|
LL | a == b;
|
||||||
|
| ^^ no implementation for `&T == T`
|
||||||
|
|
|
||||||
|
= help: the trait `PartialEq<T>` is not implemented for `&T`
|
||||||
|
help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
||||||
|
LL | fn foo2<T: PartialEq>(a: &T, b: T) where &T: PartialEq<T> {
|
||||||
|
| ++++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -15,7 +15,7 @@ note: required by a bound in `Foo::Bar`
|
||||||
|
|
|
|
||||||
LL | type Bar: ~const std::ops::Add;
|
LL | type Bar: ~const std::ops::Add;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar`
|
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar`
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | impl const Foo for NonConstAdd where NonConstAdd: ~const Add {
|
LL | impl const Foo for NonConstAdd where NonConstAdd: ~const Add {
|
||||||
| +++++++++++++++++++++++++++++
|
| +++++++++++++++++++++++++++++
|
||||||
|
|
|
@ -14,7 +14,7 @@ note: required by a bound in `foo`
|
||||||
|
|
|
|
||||||
LL | const fn foo<T>() where T: ~const Tr {}
|
LL | const fn foo<T>() where T: ~const Tr {}
|
||||||
| ^^^^^^^^^ required by this bound in `foo`
|
| ^^^^^^^^^ required by this bound in `foo`
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | pub trait Foo where (): ~const Tr {
|
LL | pub trait Foo where (): ~const Tr {
|
||||||
| +++++++++++++++++++
|
| +++++++++++++++++++
|
||||||
|
|
|
@ -20,7 +20,7 @@ note: required by a bound in `X::U`
|
||||||
|
|
|
|
||||||
LL | type U: PartialEq<T>;
|
LL | type U: PartialEq<T>;
|
||||||
| ^^^^^^^^^^^^ required by this bound in `X::U`
|
| ^^^^^^^^^^^^ required by this bound in `X::U`
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | impl<B: 'static, T> X<B> for T where &'static B: PartialEq<B> {
|
LL | impl<B: 'static, T> X<B> for T where &'static B: PartialEq<B> {
|
||||||
| ++++++++++++++++++++++++++++++
|
| ++++++++++++++++++++++++++++++
|
||||||
|
|
|
@ -13,7 +13,7 @@ help: consider annotating `a::Inner<T>` with `#[derive(Debug)]`
|
||||||
|
|
|
|
||||||
LL | #[derive(Debug)]
|
LL | #[derive(Debug)]
|
||||||
|
|
|
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | struct Outer<T>(Inner<T>) where a::Inner<T>: Debug;
|
LL | struct Outer<T>(Inner<T>) where a::Inner<T>: Debug;
|
||||||
| ++++++++++++++++++++++++
|
| ++++++++++++++++++++++++
|
||||||
|
|
|
@ -15,7 +15,7 @@ help: consider annotating `S<T>` with `#[derive(PartialEq)]`
|
||||||
|
|
|
|
||||||
LL | #[derive(PartialEq)]
|
LL | #[derive(PartialEq)]
|
||||||
|
|
|
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | pub fn foo<T>(s: S<T>, t: S<T>) where S<T>: PartialEq {
|
LL | pub fn foo<T>(s: S<T>, t: S<T>) where S<T>: PartialEq {
|
||||||
| +++++++++++++++++++++
|
| +++++++++++++++++++++
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::io::{BufRead, BufReader, Read, Write};
|
use std::io::{BufRead, BufReader, Read, Write};
|
||||||
|
|
||||||
fn issue_81421<T: Read + Write>(mut stream: T) { //~ HELP consider introducing a `where` bound
|
fn issue_81421<T: Read + Write>(mut stream: T) { //~ HELP consider introducing a `where` clause
|
||||||
let initial_message = format!("Hello world");
|
let initial_message = format!("Hello world");
|
||||||
let mut buffer: Vec<u8> = Vec::new();
|
let mut buffer: Vec<u8> = Vec::new();
|
||||||
let bytes_written = stream.write_all(initial_message.as_bytes());
|
let bytes_written = stream.write_all(initial_message.as_bytes());
|
||||||
|
|
|
@ -16,7 +16,7 @@ help: consider removing the leading `&`-reference
|
||||||
LL - let mut stream_reader = BufReader::new(&stream);
|
LL - let mut stream_reader = BufReader::new(&stream);
|
||||||
LL + let mut stream_reader = BufReader::new(stream);
|
LL + let mut stream_reader = BufReader::new(stream);
|
||||||
|
|
|
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | fn issue_81421<T: Read + Write>(mut stream: T) where &T: std::io::Read {
|
LL | fn issue_81421<T: Read + Write>(mut stream: T) where &T: std::io::Read {
|
||||||
| +++++++++++++++++++++++
|
| +++++++++++++++++++++++
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | a * b
|
||||||
| |
|
| |
|
||||||
| &T
|
| &T
|
||||||
|
|
|
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 where &T: Mul<f64> {
|
LL | fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 where &T: Mul<f64> {
|
||||||
| ++++++++++++++++++
|
| ++++++++++++++++++
|
||||||
|
|
|
@ -49,7 +49,7 @@ error[E0277]: the trait bound `u64: From<T>` is not satisfied
|
||||||
LL | <u64 as From<T>>::from;
|
LL | <u64 as From<T>>::from;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `u64`
|
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `u64`
|
||||||
|
|
|
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | fn check<T: Iterator, U: ?Sized>() where u64: From<T> {
|
LL | fn check<T: Iterator, U: ?Sized>() where u64: From<T> {
|
||||||
| ++++++++++++++++++
|
| ++++++++++++++++++
|
||||||
|
@ -60,7 +60,7 @@ error[E0277]: the trait bound `u64: From<<T as Iterator>::Item>` is not satisfie
|
||||||
LL | <u64 as From<<T as Iterator>::Item>>::from;
|
LL | <u64 as From<<T as Iterator>::Item>>::from;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
|
||||||
|
|
|
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | fn check<T: Iterator, U: ?Sized>() where u64: From<<T as Iterator>::Item> {
|
LL | fn check<T: Iterator, U: ?Sized>() where u64: From<<T as Iterator>::Item> {
|
||||||
| ++++++++++++++++++++++++++++++++++++++
|
| ++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | (a, a)
|
||||||
| ^ the trait `From<&A>` is not implemented for `&'static B`
|
| ^ the trait `From<&A>` is not implemented for `&'static B`
|
||||||
|
|
|
|
||||||
= note: required because of the requirements on the impl of `Into<&'static B>` for `&A`
|
= note: required because of the requirements on the impl of `Into<&'static B>` for `&A`
|
||||||
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
|
LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
|
||||||
| ++++++++++++++++++++++++++
|
| ++++++++++++++++++++++++++
|
||||||
|
|
Loading…
Add table
Reference in a new issue