From d8e9db0dcf0fc5cd6585a86145bfed5ea3c55031 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 16 Sep 2021 13:05:14 -0700 Subject: [PATCH 1/4] feat(rustc_parse): recover from pre-RFC-2000 const generics syntax Fixes #89013 --- compiler/rustc_parse/src/parser/path.rs | 20 ++++++++- .../issue-89013-no-assoc.rs | 16 ++++++++ .../issue-89013-no-assoc.stderr | 8 ++++ .../issue-89013-no-kw.rs | 18 ++++++++ .../issue-89013-no-kw.stderr | 35 ++++++++++++++++ .../parser-error-recovery/issue-89013-type.rs | 17 ++++++++ .../issue-89013-type.stderr | 24 +++++++++++ .../parser-error-recovery/issue-89013.rs | 19 +++++++++ .../parser-error-recovery/issue-89013.stderr | 41 +++++++++++++++++++ 9 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs create mode 100644 src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr create mode 100644 src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs create mode 100644 src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr create mode 100644 src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs create mode 100644 src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr create mode 100644 src/test/ui/const-generics/parser-error-recovery/issue-89013.rs create mode 100644 src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 953c6915068a..4e4130dfc230 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -495,11 +495,16 @@ impl<'a> Parser<'a> { None => { let after_eq = eq.shrink_to_hi(); let before_next = self.token.span.shrink_to_lo(); + let the_type_placeholder = if matches!(self.token.kind, token::Comma | token::Gt) { + " TheType" + } else { + " TheType " + }; self.struct_span_err(after_eq.to(before_next), "missing type to the right of `=`") .span_suggestion( self.sess.source_map().next_point(eq).to(before_next), "to constrain the associated type, add a type after `=`", - " TheType".to_string(), + the_type_placeholder.to_string(), Applicability::HasPlaceholders, ) .span_suggestion( @@ -572,6 +577,19 @@ impl<'a> Parser<'a> { return self.recover_const_arg(start, err).map(Some); } } + } else if self.eat_keyword_noexpect(kw::Const) { + // Detect and recover from the old, pre-RFC2000 syntax for const generics. + let mut err = self.struct_span_err( + start, + "expected lifetime, type, or constant, found keyword `const`", + ); + if self.check_const_arg() { + err.emit(); + GenericArg::Const(self.parse_const_arg()?) + } else { + let after_kw_const = self.token.span; + return self.recover_const_arg(after_kw_const, err).map(Some); + } } else { return Ok(None); }; diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs new file mode 100644 index 000000000000..99d8e9dea910 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.rs @@ -0,0 +1,16 @@ +trait Foo { + fn do_x(&self) -> [u8; N]; +} + +struct Bar; + +const T: usize = 42; + +impl Foo for Bar { +//~^ERROR expected lifetime, type, or constant, found keyword `const` + fn do_x(&self) -> [u8; 3] { + [0u8; 3] + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr new file mode 100644 index 000000000000..533d381fa313 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr @@ -0,0 +1,8 @@ +error: expected lifetime, type, or constant, found keyword `const` + --> $DIR/issue-89013-no-assoc.rs:9:10 + | +LL | impl Foo for Bar { + | ^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs new file mode 100644 index 000000000000..b73b3e291045 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs @@ -0,0 +1,18 @@ +trait Foo { + fn do_x(&self) -> [u8; N]; +} + +struct Bar; + +const T: usize = 42; + +impl Foo for Bar { +//~^ERROR cannot constrain an associated constant to a value +//~^^ERROR this trait takes 1 generic argument but 0 generic arguments +//~^^^ERROR associated type bindings are not allowed here + fn do_x(&self) -> [u8; 3] { + [0u8; 3] + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr new file mode 100644 index 000000000000..768281555767 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr @@ -0,0 +1,35 @@ +error: cannot constrain an associated constant to a value + --> $DIR/issue-89013-no-kw.rs:9:10 + | +LL | impl Foo for Bar { + | -^^^- + | | | + | | ...cannot be constrained to this value + | this associated constant... + +error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied + --> $DIR/issue-89013-no-kw.rs:9:6 + | +LL | impl Foo for Bar { + | ^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `N` + --> $DIR/issue-89013-no-kw.rs:1:7 + | +LL | trait Foo { + | ^^^ - +help: add missing generic argument + | +LL | impl Foo for Bar { + | ++ + +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-89013-no-kw.rs:9:10 + | +LL | impl Foo for Bar { + | ^^^^^ associated type not allowed here + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0229. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs new file mode 100644 index 000000000000..c34936d19762 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs @@ -0,0 +1,17 @@ +trait Foo { + fn do_x(&self) -> [u8; N]; +} + +struct Bar; + +const T: usize = 42; + +impl Foo for Bar { +//~^ERROR missing type to the right of `=` +//~^^ERROR found keyword `type` + fn do_x(&self) -> [u8; 3] { + [0u8; 3] + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr new file mode 100644 index 000000000000..0f33f4b0df60 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr @@ -0,0 +1,24 @@ +error: missing type to the right of `=` + --> $DIR/issue-89013-type.rs:9:13 + | +LL | impl Foo for Bar { + | ^ + | +help: to constrain the associated type, add a type after `=` + | +LL | impl Foo for Bar { + | +++++++ +help: remove the `=` if `N` is a type + | +LL - impl Foo for Bar { +LL + impl Foo for Bar { + | + +error: expected one of `,`, `>`, a const expression, lifetime, or type, found keyword `type` + --> $DIR/issue-89013-type.rs:9:14 + | +LL | impl Foo for Bar { + | ^^^^ expected one of `,`, `>`, a const expression, lifetime, or type + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs new file mode 100644 index 000000000000..d5ded44188a0 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs @@ -0,0 +1,19 @@ +trait Foo { + fn do_x(&self) -> [u8; N]; +} + +struct Bar; + +const T: usize = 42; + +impl Foo for Bar { +//~^ERROR expected lifetime, type, or constant, found keyword `const` +//~^^ERROR cannot constrain an associated constant to a value +//~^^^ERROR this trait takes 1 generic argument but 0 generic arguments +//~^^^^ERROR associated type bindings are not allowed here + fn do_x(&self) -> [u8; 3] { + [0u8; 3] + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr new file mode 100644 index 000000000000..3df459ce1628 --- /dev/null +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -0,0 +1,41 @@ +error: expected lifetime, type, or constant, found keyword `const` + --> $DIR/issue-89013.rs:9:14 + | +LL | impl Foo for Bar { + | ^^^^^ + +error: cannot constrain an associated constant to a value + --> $DIR/issue-89013.rs:9:10 + | +LL | impl Foo for Bar { + | -^^^^^^^^^- + | | | + | | ...cannot be constrained to this value + | this associated constant... + +error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied + --> $DIR/issue-89013.rs:9:6 + | +LL | impl Foo for Bar { + | ^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `N` + --> $DIR/issue-89013.rs:1:7 + | +LL | trait Foo { + | ^^^ - +help: add missing generic argument + | +LL | impl Foo for Bar { + | ++ + +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-89013.rs:9:10 + | +LL | impl Foo for Bar { + | ^^^^^^^^^^^ associated type not allowed here + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0107, E0229. +For more information about an error, try `rustc --explain E0107`. From 8a7c1306b43895a97c0675c6d854afa468a22aad Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Sep 2021 10:57:34 -0700 Subject: [PATCH 2/4] Use less verbose syntax for error annotations Co-authored-by: Esteban Kuber --- .../const-generics/parser-error-recovery/issue-89013.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs index d5ded44188a0..99f3549d9ac3 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs @@ -7,10 +7,10 @@ struct Bar; const T: usize = 42; impl Foo for Bar { -//~^ERROR expected lifetime, type, or constant, found keyword `const` -//~^^ERROR cannot constrain an associated constant to a value -//~^^^ERROR this trait takes 1 generic argument but 0 generic arguments -//~^^^^ERROR associated type bindings are not allowed here +//~^ ERROR expected lifetime, type, or constant, found keyword `const` +//~| ERROR cannot constrain an associated constant to a value +//~| ERROR this trait takes 1 generic argument but 0 generic arguments +//~| ERROR associated type bindings are not allowed here fn do_x(&self) -> [u8; 3] { [0u8; 3] } From befdfb5c7113b3d82d973b1acfdcc2b0d9c14ab1 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Sep 2021 12:48:58 -0700 Subject: [PATCH 3/4] Improve error messages for bad type constraints Co-authored-by: Esteban Kuber --- compiler/rustc_parse/src/parser/path.rs | 31 ++++++++++++------- .../issue-89013-no-assoc.stderr | 6 ++++ .../parser-error-recovery/issue-89013-type.rs | 1 - .../issue-89013-type.stderr | 20 ++---------- .../parser-error-recovery/issue-89013.stderr | 6 ++++ 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 4e4130dfc230..c7d080a80fe6 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -495,25 +495,28 @@ impl<'a> Parser<'a> { None => { let after_eq = eq.shrink_to_hi(); let before_next = self.token.span.shrink_to_lo(); - let the_type_placeholder = if matches!(self.token.kind, token::Comma | token::Gt) { - " TheType" - } else { - " TheType " - }; - self.struct_span_err(after_eq.to(before_next), "missing type to the right of `=`") - .span_suggestion( + let mut err = self + .struct_span_err(after_eq.to(before_next), "missing type to the right of `=`"); + if matches!(self.token.kind, token::Comma | token::Gt) { + err.span_suggestion( self.sess.source_map().next_point(eq).to(before_next), "to constrain the associated type, add a type after `=`", - the_type_placeholder.to_string(), + " TheType".to_string(), Applicability::HasPlaceholders, - ) - .span_suggestion( + ); + err.span_suggestion( eq.to(before_next), &format!("remove the `=` if `{}` is a type", ident), String::new(), Applicability::MaybeIncorrect, ) - .emit(); + } else { + err.span_label( + self.token.span, + &format!("expected type, found {}", super::token_descr(&self.token)), + ) + }; + return Err(err); } } Ok(self.mk_ty(span, ast::TyKind::Err)) @@ -584,6 +587,12 @@ impl<'a> Parser<'a> { "expected lifetime, type, or constant, found keyword `const`", ); if self.check_const_arg() { + err.span_suggestion_verbose( + start.until(self.token.span), + "the `const` keyword is only needed in the definition of the type", + String::new(), + Applicability::MaybeIncorrect, + ); err.emit(); GenericArg::Const(self.parse_const_arg()?) } else { diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr index 533d381fa313..ddddd86ab9c0 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-assoc.stderr @@ -3,6 +3,12 @@ error: expected lifetime, type, or constant, found keyword `const` | LL | impl Foo for Bar { | ^^^^^ + | +help: the `const` keyword is only needed in the definition of the type + | +LL - impl Foo for Bar { +LL + impl Foo<3> for Bar { + | error: aborting due to previous error diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs index c34936d19762..0ec6762b6e28 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.rs @@ -8,7 +8,6 @@ const T: usize = 42; impl Foo for Bar { //~^ERROR missing type to the right of `=` -//~^^ERROR found keyword `type` fn do_x(&self) -> [u8; 3] { [0u8; 3] } diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr index 0f33f4b0df60..f0d0d90c774f 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-type.stderr @@ -2,23 +2,7 @@ error: missing type to the right of `=` --> $DIR/issue-89013-type.rs:9:13 | LL | impl Foo for Bar { - | ^ - | -help: to constrain the associated type, add a type after `=` - | -LL | impl Foo for Bar { - | +++++++ -help: remove the `=` if `N` is a type - | -LL - impl Foo for Bar { -LL + impl Foo for Bar { - | + | ^---- expected type, found keyword `type` -error: expected one of `,`, `>`, a const expression, lifetime, or type, found keyword `type` - --> $DIR/issue-89013-type.rs:9:14 - | -LL | impl Foo for Bar { - | ^^^^ expected one of `,`, `>`, a const expression, lifetime, or type - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr index 3df459ce1628..a60e17aef589 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -3,6 +3,12 @@ error: expected lifetime, type, or constant, found keyword `const` | LL | impl Foo for Bar { | ^^^^^ + | +help: the `const` keyword is only needed in the definition of the type + | +LL - impl Foo for Bar { +LL + impl Foo for Bar { + | error: cannot constrain an associated constant to a value --> $DIR/issue-89013.rs:9:10 From 105b60f2501fac061284ea7f5fbb8fb3f8134a92 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Sep 2021 15:56:45 -0700 Subject: [PATCH 4/4] feat(rustc_typeck): avoid erroring with "wrong number of generics" if there's other problems As shown in the two test requirements that got updated, if there's other problems, then those other problems are probably the root cause of the incorrect generics count. --- compiler/rustc_hir/src/hir.rs | 10 +++++++++ compiler/rustc_typeck/src/astconv/generics.rs | 2 +- .../issue-89013-no-kw.rs | 5 ++--- .../issue-89013-no-kw.stderr | 21 ++----------------- .../parser-error-recovery/issue-89013.rs | 1 - .../parser-error-recovery/issue-89013.stderr | 21 ++----------------- 6 files changed, 17 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5655c4c0e973..d952d5a544d7 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -384,6 +384,16 @@ impl GenericArgs<'_> { self.args.iter().any(|arg| matches!(arg, GenericArg::Type(_))) } + pub fn has_err(&self) -> bool { + self.args.iter().any(|arg| match arg { + GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err), + _ => false, + }) || self.bindings.iter().any(|arg| match arg.kind { + TypeBindingKind::Equality { ty } => matches!(ty.kind, TyKind::Err), + _ => false, + }) + } + #[inline] pub fn num_type_params(&self) -> usize { self.args.iter().filter(|arg| matches!(arg, GenericArg::Type(_))).count() diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index fd0544a47bb7..92fc18854ee7 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -601,7 +601,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { def_id, ) .diagnostic() - .emit(); + .emit_unless(gen_args.has_err()); false }; diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs index b73b3e291045..19e0f38d320c 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs @@ -7,9 +7,8 @@ struct Bar; const T: usize = 42; impl Foo for Bar { -//~^ERROR cannot constrain an associated constant to a value -//~^^ERROR this trait takes 1 generic argument but 0 generic arguments -//~^^^ERROR associated type bindings are not allowed here +//~^ ERROR cannot constrain an associated constant to a value +//~| ERROR associated type bindings are not allowed here fn do_x(&self) -> [u8; 3] { [0u8; 3] } diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr index 768281555767..bbca92ad63a9 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr @@ -7,29 +7,12 @@ LL | impl Foo for Bar { | | ...cannot be constrained to this value | this associated constant... -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied - --> $DIR/issue-89013-no-kw.rs:9:6 - | -LL | impl Foo for Bar { - | ^^^ expected 1 generic argument - | -note: trait defined here, with 1 generic parameter: `N` - --> $DIR/issue-89013-no-kw.rs:1:7 - | -LL | trait Foo { - | ^^^ - -help: add missing generic argument - | -LL | impl Foo for Bar { - | ++ - error[E0229]: associated type bindings are not allowed here --> $DIR/issue-89013-no-kw.rs:9:10 | LL | impl Foo for Bar { | ^^^^^ associated type not allowed here -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0229. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0229`. diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs index 99f3549d9ac3..ca1158a2f6d1 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.rs @@ -9,7 +9,6 @@ const T: usize = 42; impl Foo for Bar { //~^ ERROR expected lifetime, type, or constant, found keyword `const` //~| ERROR cannot constrain an associated constant to a value -//~| ERROR this trait takes 1 generic argument but 0 generic arguments //~| ERROR associated type bindings are not allowed here fn do_x(&self) -> [u8; 3] { [0u8; 3] diff --git a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr index a60e17aef589..85379d3f06e4 100644 --- a/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr +++ b/src/test/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -19,29 +19,12 @@ LL | impl Foo for Bar { | | ...cannot be constrained to this value | this associated constant... -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied - --> $DIR/issue-89013.rs:9:6 - | -LL | impl Foo for Bar { - | ^^^ expected 1 generic argument - | -note: trait defined here, with 1 generic parameter: `N` - --> $DIR/issue-89013.rs:1:7 - | -LL | trait Foo { - | ^^^ - -help: add missing generic argument - | -LL | impl Foo for Bar { - | ++ - error[E0229]: associated type bindings are not allowed here --> $DIR/issue-89013.rs:9:10 | LL | impl Foo for Bar { | ^^^^^^^^^^^ associated type not allowed here -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0107, E0229. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0229`.