mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Move an impl-Trait check from AST validation to AST lowering
This commit is contained in:
parent
6faf0bd3e5
commit
442f39582d
@ -34,7 +34,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
modifiers: Option<ast::TraitBoundModifiers>,
|
modifiers: Option<ast::TraitBoundModifiers>,
|
||||||
) -> hir::QPath<'hir> {
|
) -> hir::QPath<'hir> {
|
||||||
let qself_position = qself.as_ref().map(|q| q.position);
|
let qself_position = qself.as_ref().map(|q| q.position);
|
||||||
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
|
let qself = qself
|
||||||
|
.as_ref()
|
||||||
|
// Reject cases like `<impl Trait>::Assoc` and `<impl Trait as Trait>::Assoc`.
|
||||||
|
.map(|q| self.lower_ty(&q.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Path)));
|
||||||
|
|
||||||
let partial_res =
|
let partial_res =
|
||||||
self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
|
self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
|
||||||
@ -75,6 +78,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Only permit `impl Trait` in the final segment. E.g., we permit `Option<impl Trait>`,
|
||||||
|
// `option::Option<T>::Xyz<impl Trait>` and reject `option::Option<impl Trait>::Xyz`.
|
||||||
|
let itctx = |i| {
|
||||||
|
if i + 1 == p.segments.len() {
|
||||||
|
itctx
|
||||||
|
} else {
|
||||||
|
ImplTraitContext::Disallowed(ImplTraitPosition::Path)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let path_span_lo = p.span.shrink_to_lo();
|
let path_span_lo = p.span.shrink_to_lo();
|
||||||
let proj_start = p.segments.len() - unresolved_segments;
|
let proj_start = p.segments.len() - unresolved_segments;
|
||||||
let path = self.arena.alloc(hir::Path {
|
let path = self.arena.alloc(hir::Path {
|
||||||
@ -121,7 +134,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
segment,
|
segment,
|
||||||
param_mode,
|
param_mode,
|
||||||
generic_args_mode,
|
generic_args_mode,
|
||||||
itctx,
|
itctx(i),
|
||||||
bound_modifier_allowed_features.clone(),
|
bound_modifier_allowed_features.clone(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -185,7 +198,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
segment,
|
segment,
|
||||||
param_mode,
|
param_mode,
|
||||||
generic_args_mode,
|
generic_args_mode,
|
||||||
itctx,
|
itctx(i),
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
let qpath = hir::QPath::TypeRelative(ty, hir_segment);
|
let qpath = hir::QPath::TypeRelative(ty, hir_segment);
|
||||||
|
@ -146,8 +146,6 @@ ast_passes_generic_before_constraints = generic arguments must come before the f
|
|||||||
|
|
||||||
ast_passes_generic_default_trailing = generic parameters with a default must be trailing
|
ast_passes_generic_default_trailing = generic parameters with a default must be trailing
|
||||||
|
|
||||||
ast_passes_impl_trait_path = `impl Trait` is not allowed in path parameters
|
|
||||||
|
|
||||||
ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
|
ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
|
||||||
.help = remove one of these features
|
.help = remove one of these features
|
||||||
|
|
||||||
|
@ -80,10 +80,6 @@ struct AstValidator<'a> {
|
|||||||
|
|
||||||
disallow_tilde_const: Option<TildeConstReason>,
|
disallow_tilde_const: Option<TildeConstReason>,
|
||||||
|
|
||||||
/// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
|
|
||||||
/// or `Foo::Bar<impl Trait>`
|
|
||||||
is_impl_trait_banned: bool,
|
|
||||||
|
|
||||||
/// Used to ban explicit safety on foreign items when the extern block is not marked as unsafe.
|
/// Used to ban explicit safety on foreign items when the extern block is not marked as unsafe.
|
||||||
extern_mod_safety: Option<Safety>,
|
extern_mod_safety: Option<Safety>,
|
||||||
|
|
||||||
@ -123,12 +119,6 @@ impl<'a> AstValidator<'a> {
|
|||||||
self.extern_mod_safety = old;
|
self.extern_mod_safety = old;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
|
|
||||||
let old = mem::replace(&mut self.is_impl_trait_banned, true);
|
|
||||||
f(self);
|
|
||||||
self.is_impl_trait_banned = old;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_tilde_const(
|
fn with_tilde_const(
|
||||||
&mut self,
|
&mut self,
|
||||||
disallowed: Option<TildeConstReason>,
|
disallowed: Option<TildeConstReason>,
|
||||||
@ -213,37 +203,6 @@ impl<'a> AstValidator<'a> {
|
|||||||
.with_tilde_const(Some(TildeConstReason::TraitObject), |this| {
|
.with_tilde_const(Some(TildeConstReason::TraitObject), |this| {
|
||||||
visit::walk_ty(this, t)
|
visit::walk_ty(this, t)
|
||||||
}),
|
}),
|
||||||
TyKind::Path(qself, path) => {
|
|
||||||
// We allow these:
|
|
||||||
// - `Option<impl Trait>`
|
|
||||||
// - `option::Option<impl Trait>`
|
|
||||||
// - `option::Option<T>::Foo<impl Trait>`
|
|
||||||
//
|
|
||||||
// But not these:
|
|
||||||
// - `<impl Trait>::Foo`
|
|
||||||
// - `option::Option<impl Trait>::Foo`.
|
|
||||||
//
|
|
||||||
// To implement this, we disallow `impl Trait` from `qself`
|
|
||||||
// (for cases like `<impl Trait>::Foo>`)
|
|
||||||
// but we allow `impl Trait` in `GenericArgs`
|
|
||||||
// iff there are no more PathSegments.
|
|
||||||
if let Some(qself) = qself {
|
|
||||||
// `impl Trait` in `qself` is always illegal
|
|
||||||
self.with_banned_impl_trait(|this| this.visit_ty(&qself.ty));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that there should be a call to visit_path here,
|
|
||||||
// so if any logic is added to process `Path`s a call to it should be
|
|
||||||
// added both in visit_path and here. This code mirrors visit::walk_path.
|
|
||||||
for (i, segment) in path.segments.iter().enumerate() {
|
|
||||||
// Allow `impl Trait` iff we're on the final path segment
|
|
||||||
if i == path.segments.len() - 1 {
|
|
||||||
self.visit_path_segment(segment);
|
|
||||||
} else {
|
|
||||||
self.with_banned_impl_trait(|this| this.visit_path_segment(segment));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => visit::walk_ty(self, t),
|
_ => visit::walk_ty(self, t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -737,10 +696,6 @@ impl<'a> AstValidator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TyKind::ImplTrait(_, bounds) => {
|
TyKind::ImplTrait(_, bounds) => {
|
||||||
if self.is_impl_trait_banned {
|
|
||||||
self.dcx().emit_err(errors::ImplTraitPath { span: ty.span });
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(outer_impl_trait_sp) = self.outer_impl_trait {
|
if let Some(outer_impl_trait_sp) = self.outer_impl_trait {
|
||||||
self.dcx().emit_err(errors::NestedImplTrait {
|
self.dcx().emit_err(errors::NestedImplTrait {
|
||||||
span: ty.span,
|
span: ty.span,
|
||||||
@ -1729,7 +1684,6 @@ pub fn check_crate(
|
|||||||
has_proc_macro_decls: false,
|
has_proc_macro_decls: false,
|
||||||
outer_impl_trait: None,
|
outer_impl_trait: None,
|
||||||
disallow_tilde_const: Some(TildeConstReason::Item),
|
disallow_tilde_const: Some(TildeConstReason::Item),
|
||||||
is_impl_trait_banned: false,
|
|
||||||
extern_mod_safety: None,
|
extern_mod_safety: None,
|
||||||
lint_buffer: lints,
|
lint_buffer: lints,
|
||||||
};
|
};
|
||||||
|
@ -418,13 +418,6 @@ pub(crate) struct TraitObjectBound {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(ast_passes_impl_trait_path, code = E0667)]
|
|
||||||
pub(crate) struct ImplTraitPath {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_nested_impl_trait, code = E0666)]
|
#[diag(ast_passes_nested_impl_trait, code = E0666)]
|
||||||
pub(crate) struct NestedImplTrait {
|
pub(crate) struct NestedImplTrait {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
#### Note: this error code is no longer emitted by the compiler.
|
||||||
|
|
||||||
`impl Trait` is not allowed in path parameters.
|
`impl Trait` is not allowed in path parameters.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0667
|
```ignore (removed error code)
|
||||||
fn some_fn(mut x: impl Iterator) -> <impl Iterator>::Item { // error!
|
fn some_fn(mut x: impl Iterator) -> <impl Iterator>::Item { // error!
|
||||||
x.next().unwrap()
|
x.next().unwrap()
|
||||||
}
|
}
|
||||||
@ -11,7 +13,7 @@ fn some_fn(mut x: impl Iterator) -> <impl Iterator>::Item { // error!
|
|||||||
You cannot use `impl Trait` in path parameters. If you want something
|
You cannot use `impl Trait` in path parameters. If you want something
|
||||||
equivalent, you can do this instead:
|
equivalent, you can do this instead:
|
||||||
|
|
||||||
```
|
```ignore (removed error code)
|
||||||
fn some_fn<T: Iterator>(mut x: T) -> T::Item { // ok!
|
fn some_fn<T: Iterator>(mut x: T) -> T::Item { // ok!
|
||||||
x.next().unwrap()
|
x.next().unwrap()
|
||||||
}
|
}
|
||||||
|
@ -1203,15 +1203,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||||||
err.emit()
|
err.emit()
|
||||||
} else if let Err(reported) = qself_ty.error_reported() {
|
} else if let Err(reported) = qself_ty.error_reported() {
|
||||||
reported
|
reported
|
||||||
} else if let ty::Alias(ty::Opaque, alias_ty) = qself_ty.kind() {
|
|
||||||
// `<impl Trait as OtherTrait>::Assoc` makes no sense.
|
|
||||||
struct_span_code_err!(
|
|
||||||
self.dcx(),
|
|
||||||
tcx.def_span(alias_ty.def_id),
|
|
||||||
E0667,
|
|
||||||
"`impl Trait` is not allowed in path parameters"
|
|
||||||
)
|
|
||||||
.emit() // Already reported in an earlier stage.
|
|
||||||
} else {
|
} else {
|
||||||
self.maybe_report_similar_assoc_fn(span, qself_ty, qself)?;
|
self.maybe_report_similar_assoc_fn(span, qself_ty, qself)?;
|
||||||
|
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
//@ known-bug: rust-lang/rust#126725
|
|
||||||
trait Foo {
|
|
||||||
fn foo<'a>(&'a self) -> <&'a impl Sized as Bar>::Output;
|
|
||||||
}
|
|
||||||
|
|
||||||
trait Bar {
|
|
||||||
type Output;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct X(i32);
|
|
||||||
|
|
||||||
impl<'a> Bar for &'a X {
|
|
||||||
type Output = &'a i32;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Foo for X {
|
|
||||||
fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,30 +10,27 @@ fn path_parametrized_type_is_allowed() -> option::Option<impl Debug> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
||||||
//~^ ERROR `impl Trait` is not allowed in path parameters
|
//~^ ERROR `impl Trait` is not allowed in paths
|
||||||
//~| ERROR `impl Trait` is not allowed in path parameters
|
|
||||||
x.next().unwrap()
|
x.next().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn projection_with_named_trait_is_disallowed(mut x: impl Iterator)
|
fn projection_with_named_trait_is_disallowed(mut x: impl Iterator)
|
||||||
-> <impl Iterator as Iterator>::Item
|
-> <impl Iterator as Iterator>::Item
|
||||||
//~^ ERROR `impl Trait` is not allowed in path parameters
|
//~^ ERROR `impl Trait` is not allowed in paths
|
||||||
{
|
{
|
||||||
x.next().unwrap()
|
x.next().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn projection_with_named_trait_inside_path_is_disallowed()
|
fn projection_with_named_trait_inside_path_is_disallowed()
|
||||||
-> <::std::ops::Range<impl Debug> as Iterator>::Item
|
-> <::std::ops::Range<impl Debug> as Iterator>::Item
|
||||||
//~^ ERROR `impl Trait` is not allowed in path parameters
|
//~^ ERROR `impl Trait` is not allowed in paths
|
||||||
//~| ERROR `impl Debug: Step` is not satisfied
|
|
||||||
{
|
{
|
||||||
//~^ ERROR `impl Debug: Step` is not satisfied
|
|
||||||
(1i32..100).next().unwrap()
|
(1i32..100).next().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()
|
fn projection_from_impl_trait_inside_dyn_trait_is_disallowed()
|
||||||
-> <dyn Iterator<Item = impl Debug> as Iterator>::Item
|
-> <dyn Iterator<Item = impl Debug> as Iterator>::Item
|
||||||
//~^ ERROR `impl Trait` is not allowed in path parameters
|
//~^ ERROR `impl Trait` is not allowed in paths
|
||||||
{
|
{
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
@ -1,73 +1,35 @@
|
|||||||
error[E0667]: `impl Trait` is not allowed in path parameters
|
error[E0562]: `impl Trait` is not allowed in paths
|
||||||
--> $DIR/impl_trait_projections.rs:12:51
|
--> $DIR/impl_trait_projections.rs:12:51
|
||||||
|
|
|
|
||||||
LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0667]: `impl Trait` is not allowed in path parameters
|
error[E0562]: `impl Trait` is not allowed in paths
|
||||||
--> $DIR/impl_trait_projections.rs:19:9
|
--> $DIR/impl_trait_projections.rs:18:9
|
||||||
|
|
|
|
||||||
LL | -> <impl Iterator as Iterator>::Item
|
LL | -> <impl Iterator as Iterator>::Item
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0667]: `impl Trait` is not allowed in path parameters
|
error[E0562]: `impl Trait` is not allowed in paths
|
||||||
--> $DIR/impl_trait_projections.rs:26:27
|
--> $DIR/impl_trait_projections.rs:25:27
|
||||||
|
|
|
|
||||||
LL | -> <::std::ops::Range<impl Debug> as Iterator>::Item
|
LL | -> <::std::ops::Range<impl Debug> as Iterator>::Item
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error[E0667]: `impl Trait` is not allowed in path parameters
|
error[E0562]: `impl Trait` is not allowed in paths
|
||||||
--> $DIR/impl_trait_projections.rs:35:29
|
--> $DIR/impl_trait_projections.rs:32:29
|
||||||
|
|
|
|
||||||
LL | -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
|
LL | -> <dyn Iterator<Item = impl Debug> as Iterator>::Item
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0667]: `impl Trait` is not allowed in path parameters
|
|
||||||
--> $DIR/impl_trait_projections.rs:12:51
|
|
||||||
|
|
|
|
||||||
LL | fn projection_is_disallowed(x: impl Iterator) -> <impl Iterator>::Item {
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `impl Debug: Step` is not satisfied
|
error: aborting due to 4 previous errors
|
||||||
--> $DIR/impl_trait_projections.rs:26:8
|
|
||||||
|
|
|
||||||
LL | -> <::std::ops::Range<impl Debug> as Iterator>::Item
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Step` is not implemented for `impl Debug`, which is required by `std::ops::Range<impl Debug>: Iterator`
|
|
||||||
|
|
|
||||||
= help: the following other types implement trait `Step`:
|
|
||||||
Char
|
|
||||||
Ipv4Addr
|
|
||||||
Ipv6Addr
|
|
||||||
char
|
|
||||||
i128
|
|
||||||
i16
|
|
||||||
i32
|
|
||||||
i64
|
|
||||||
and 8 others
|
|
||||||
= note: required for `std::ops::Range<impl Debug>` to implement `Iterator`
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `impl Debug: Step` is not satisfied
|
For more information about this error, try `rustc --explain E0562`.
|
||||||
--> $DIR/impl_trait_projections.rs:29:1
|
|
||||||
|
|
|
||||||
LL | / {
|
|
||||||
LL | |
|
|
||||||
LL | | (1i32..100).next().unwrap()
|
|
||||||
LL | | }
|
|
||||||
| |_^ the trait `Step` is not implemented for `impl Debug`, which is required by `std::ops::Range<impl Debug>: Iterator`
|
|
||||||
|
|
|
||||||
= help: the following other types implement trait `Step`:
|
|
||||||
Char
|
|
||||||
Ipv4Addr
|
|
||||||
Ipv6Addr
|
|
||||||
char
|
|
||||||
i128
|
|
||||||
i16
|
|
||||||
i32
|
|
||||||
i64
|
|
||||||
and 8 others
|
|
||||||
= note: required for `std::ops::Range<impl Debug>` to implement `Iterator`
|
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0667.
|
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
22
tests/ui/impl-trait/in-trait/bad-projection-from-opaque.rs
Normal file
22
tests/ui/impl-trait/in-trait/bad-projection-from-opaque.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// issue: rust-lang/rust#126725
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn foo<'a>() -> <&'a impl Sized as Bar>::Output;
|
||||||
|
//~^ ERROR `impl Trait` is not allowed in paths
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Bar {
|
||||||
|
type Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Bar for &'a () {
|
||||||
|
type Output = &'a i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for () {
|
||||||
|
fn foo<'a>() -> <&'a Self as Bar>::Output {
|
||||||
|
&0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,11 @@
|
|||||||
|
error[E0562]: `impl Trait` is not allowed in paths
|
||||||
|
--> $DIR/bad-projection-from-opaque.rs:4:26
|
||||||
|
|
|
||||||
|
LL | fn foo<'a>() -> <&'a impl Sized as Bar>::Output;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0562`.
|
@ -6,7 +6,7 @@
|
|||||||
pub trait Bar { }
|
pub trait Bar { }
|
||||||
pub trait Quux<T> { type Assoc; }
|
pub trait Quux<T> { type Assoc; }
|
||||||
pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
|
pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
|
||||||
//~^ ERROR `impl Trait` is not allowed in path parameters
|
//~^ ERROR `impl Trait` is not allowed in paths
|
||||||
impl<T> Quux<T> for () { type Assoc = u32; }
|
impl<T> Quux<T> for () { type Assoc = u32; }
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
error[E0667]: `impl Trait` is not allowed in path parameters
|
error[E0562]: `impl Trait` is not allowed in paths
|
||||||
--> $DIR/issue-57979-impl-trait-in-path.rs:8:48
|
--> $DIR/issue-57979-impl-trait-in-path.rs:8:48
|
||||||
|
|
|
|
||||||
LL | pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
|
LL | pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0667`.
|
For more information about this error, try `rustc --explain E0562`.
|
||||||
|
Loading…
Reference in New Issue
Block a user