better error for binder on associated type bound
This commit is contained in:
parent
1f7fb6413d
commit
b65265b5e1
@ -2483,7 +2483,7 @@ pub struct TraitRef {
|
|||||||
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub struct PolyTraitRef {
|
pub struct PolyTraitRef {
|
||||||
/// The `'a` in `<'a> Foo<&'a T>`.
|
/// The `'a` in `for<'a> Foo<&'a T>`.
|
||||||
pub bound_generic_params: Vec<GenericParam>,
|
pub bound_generic_params: Vec<GenericParam>,
|
||||||
|
|
||||||
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
|
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
|
||||||
|
@ -518,10 +518,20 @@ impl<'a> Parser<'a> {
|
|||||||
match arg {
|
match arg {
|
||||||
Some(arg) => {
|
Some(arg) => {
|
||||||
if self.check(&token::Colon) | self.check(&token::Eq) {
|
if self.check(&token::Colon) | self.check(&token::Eq) {
|
||||||
let (ident, gen_args) = match self.get_ident_from_generic_arg(arg) {
|
let arg_span = arg.span();
|
||||||
|
let (binder, ident, gen_args) = match self.get_ident_from_generic_arg(&arg) {
|
||||||
Ok(ident_gen_args) => ident_gen_args,
|
Ok(ident_gen_args) => ident_gen_args,
|
||||||
Err(arg) => return Ok(Some(AngleBracketedArg::Arg(arg))),
|
Err(()) => return Ok(Some(AngleBracketedArg::Arg(arg))),
|
||||||
};
|
};
|
||||||
|
if binder.is_some() {
|
||||||
|
// FIXME(compiler-errors): this could be improved by suggesting lifting
|
||||||
|
// this up to the trait, at least before this becomes real syntax.
|
||||||
|
// e.g. `Trait<for<'a> Assoc = Ty>` -> `for<'a> Trait<Assoc = Ty>`
|
||||||
|
return Err(self.struct_span_err(
|
||||||
|
arg_span,
|
||||||
|
"`for<...>` is not allowed on associated type bounds",
|
||||||
|
));
|
||||||
|
}
|
||||||
let kind = if self.eat(&token::Colon) {
|
let kind = if self.eat(&token::Colon) {
|
||||||
// Parse associated type constraint bound.
|
// Parse associated type constraint bound.
|
||||||
|
|
||||||
@ -700,18 +710,32 @@ impl<'a> Parser<'a> {
|
|||||||
Ok(Some(arg))
|
Ok(Some(arg))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Given a arg inside of generics, we try to destructure it as if it were the LHS in
|
||||||
|
/// `LHS = ...`, i.e. an associated type binding.
|
||||||
|
/// This returns (optionally, if they are present) any `for<'a, 'b>` binder args, the
|
||||||
|
/// identifier, and any GAT arguments.
|
||||||
fn get_ident_from_generic_arg(
|
fn get_ident_from_generic_arg(
|
||||||
&self,
|
&self,
|
||||||
gen_arg: GenericArg,
|
gen_arg: &GenericArg,
|
||||||
) -> Result<(Ident, Option<GenericArgs>), GenericArg> {
|
) -> Result<(Option<Vec<ast::GenericParam>>, Ident, Option<GenericArgs>), ()> {
|
||||||
if let GenericArg::Type(ty) = &gen_arg
|
if let GenericArg::Type(ty) = gen_arg {
|
||||||
&& let ast::TyKind::Path(qself, path) = &ty.kind
|
if let ast::TyKind::Path(qself, path) = &ty.kind
|
||||||
&& qself.is_none()
|
&& qself.is_none()
|
||||||
&& path.segments.len() == 1
|
&& let [seg] = path.segments.as_slice()
|
||||||
{
|
{
|
||||||
let seg = &path.segments[0];
|
return Ok((None, seg.ident, seg.args.as_deref().cloned()));
|
||||||
return Ok((seg.ident, seg.args.as_deref().cloned()));
|
} else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
|
||||||
|
&& let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None)] =
|
||||||
|
bounds.as_slice()
|
||||||
|
&& let [seg] = trait_ref.trait_ref.path.segments.as_slice()
|
||||||
|
{
|
||||||
|
return Ok((
|
||||||
|
Some(trait_ref.bound_generic_params.clone()),
|
||||||
|
seg.ident,
|
||||||
|
seg.args.as_deref().cloned(),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(gen_arg)
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
src/test/ui/associated-type-bounds/binder-on-bound.rs
Normal file
11
src/test/ui/associated-type-bounds/binder-on-bound.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#![feature(generic_associated_types)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type Bound<'a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo() where Trait<for<'a> Bound<'a> = &'a ()> {
|
||||||
|
//~^ ERROR `for<...>` is not allowed on associated type bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,8 @@
|
|||||||
|
error: `for<...>` is not allowed on associated type bounds
|
||||||
|
--> $DIR/binder-on-bound.rs:7:22
|
||||||
|
|
|
||||||
|
LL | fn foo() where Trait<for<'a> Bound<'a> = &'a ()> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user