Rollup merge of #91208 - estebank:eq-constraint, r=cjgillot
Account for incorrect `where T::Assoc = Ty` bound Provide suggestoin to constrain trait bound for associated type. Revert incorrect changes to `missing-bounds` test. Address part of #20041.
This commit is contained in:
commit
7c5bcd548b
@ -23,7 +23,7 @@ use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi;
|
||||
use std::mem;
|
||||
use std::ops::DerefMut;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
const MORE_EXTERN: &str =
|
||||
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
|
||||
@ -1714,6 +1714,53 @@ fn deny_equality_constraints(
|
||||
}
|
||||
}
|
||||
}
|
||||
// Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
|
||||
if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind {
|
||||
if let [potential_param, potential_assoc] = &full_path.segments[..] {
|
||||
for param in &generics.params {
|
||||
if param.ident == potential_param.ident {
|
||||
for bound in ¶m.bounds {
|
||||
if let ast::GenericBound::Trait(trait_ref, TraitBoundModifier::None) = bound
|
||||
{
|
||||
if let [trait_segment] = &trait_ref.trait_ref.path.segments[..] {
|
||||
let assoc = pprust::path_to_string(&ast::Path::from_ident(
|
||||
potential_assoc.ident,
|
||||
));
|
||||
let ty = pprust::ty_to_string(&predicate.rhs_ty);
|
||||
let (args, span) = match &trait_segment.args {
|
||||
Some(args) => match args.deref() {
|
||||
ast::GenericArgs::AngleBracketed(args) => {
|
||||
let Some(arg) = args.args.last() else {
|
||||
continue;
|
||||
};
|
||||
(
|
||||
format!(", {} = {}", assoc, ty),
|
||||
arg.span().shrink_to_hi(),
|
||||
)
|
||||
}
|
||||
_ => continue,
|
||||
},
|
||||
None => (
|
||||
format!("<{} = {}>", assoc, ty),
|
||||
trait_segment.span().shrink_to_hi(),
|
||||
),
|
||||
};
|
||||
err.multipart_suggestion(
|
||||
&format!(
|
||||
"if `{}::{}` is an associated type you're trying to set, \
|
||||
use the associated type binding syntax",
|
||||
trait_segment.ident, potential_assoc.ident,
|
||||
),
|
||||
vec![(span, args), (predicate.span, String::new())],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err.note(
|
||||
"see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information",
|
||||
);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#![feature(iter_is_partitioned)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(let_else)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
pub mod ast_validation;
|
||||
|
15
src/test/ui/generic-associated-types/equality-bound.rs
Normal file
15
src/test/ui/generic-associated-types/equality-bound.rs
Normal file
@ -0,0 +1,15 @@
|
||||
fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
panic!()
|
||||
}
|
||||
fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
panic!()
|
||||
}
|
||||
fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
//~| ERROR failed to resolve: use of undeclared type `I`
|
||||
panic!()
|
||||
}
|
||||
|
||||
fn main() {}
|
43
src/test/ui/generic-associated-types/equality-bound.stderr
Normal file
43
src/test/ui/generic-associated-types/equality-bound.stderr
Normal file
@ -0,0 +1,43 @@
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:1:51
|
||||
|
|
||||
LL | fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
|
||||
| ^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
|
||||
LL + fn sum<I: Iterator<Item = (), Item = i32>>(i: I) -> i32 where {
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:5:41
|
||||
|
|
||||
LL | fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
|
||||
| ^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL - fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
|
||||
LL + fn sum2<I: Iterator<Item = i32>>(i: I) -> i32 where {
|
||||
|
|
||||
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/equality-bound.rs:9:41
|
||||
|
|
||||
LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
|
||||
| ^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
|
||||
error[E0433]: failed to resolve: use of undeclared type `I`
|
||||
--> $DIR/equality-bound.rs:9:41
|
||||
|
|
||||
LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
|
||||
| ^ use of undeclared type `I`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
@ -34,11 +34,12 @@ impl<B: std::ops::Add<Output = B>> Add for D<B> {
|
||||
|
||||
struct E<B>(B);
|
||||
|
||||
impl<B: Add> Add for E<B> where B: Add<Output = B> {
|
||||
impl<B: Add> Add for E<B> where B: Add<Output = B>, B: Add<Output = B> {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
Self(self.0 + rhs.0)
|
||||
Self(self.0 + rhs.0) //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,11 +34,12 @@ impl<B> Add for D<B> {
|
||||
|
||||
struct E<B>(B);
|
||||
|
||||
impl<B: Add> Add for E<B> where B: Add<Output = B> {
|
||||
impl<B: Add> Add for E<B> where <B as Add>::Output = B {
|
||||
//~^ ERROR equality constraints are not yet supported in `where` clauses
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
Self(self.0 + rhs.0)
|
||||
Self(self.0 + rhs.0) //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,15 @@
|
||||
error: equality constraints are not yet supported in `where` clauses
|
||||
--> $DIR/missing-bounds.rs:37:33
|
||||
|
|
||||
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ not supported
|
||||
|
|
||||
= note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
|
||||
help: if `Output` is an associated type you're trying to set, use the associated type binding syntax
|
||||
|
|
||||
LL | impl<B: Add> Add for E<B> where B: Add<Output = B> {
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/missing-bounds.rs:11:11
|
||||
|
|
||||
@ -43,7 +55,23 @@ help: consider restricting type parameter `B`
|
||||
LL | impl<B: std::ops::Add<Output = B>> Add for D<B> {
|
||||
| +++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/missing-bounds.rs:42:14
|
||||
|
|
||||
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
|
||||
| - this type parameter
|
||||
...
|
||||
LL | Self(self.0 + rhs.0)
|
||||
| ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
|
||||
|
|
||||
= note: expected type parameter `B`
|
||||
found associated type `<B as Add>::Output`
|
||||
help: consider further restricting type parameter `B`
|
||||
|
|
||||
LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B, B: Add<Output = B> {
|
||||
| ++++++++++++++++++++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0369.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user