Skip to content

Impl trait diagnostic tweaks #119703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/rustc_ast_lowering/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ ast_lowering_misplaced_double_dot =
.note = only allowed in tuple, tuple struct, and slice patterns

ast_lowering_misplaced_impl_trait =
`impl Trait` only allowed in function and inherent method argument and return types, not in {$position}
`impl Trait` is not allowed in {$position}
.note = `impl Trait` is only allowed in arguments and return types of functions and methods

ast_lowering_misplaced_relax_trait_bound =
`?Trait` bounds are only permitted at the point where a type parameter is declared
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub enum AssocTyParenthesesSub {

#[derive(Diagnostic)]
#[diag(ast_lowering_misplaced_impl_trait, code = "E0562")]
#[note]
pub struct MisplacedImplTrait<'a> {
#[primary_span]
pub span: Span,
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
}
ItemKind::Static(box ast::StaticItem { ty: t, mutability: m, expr: e }) => {
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
let (ty, body_id) =
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
hir::ItemKind::Static(ty, *m, body_id)
}
ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
Expand All @@ -191,7 +192,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
Const::No,
id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.lower_const_item(ty, span, expr.as_deref()),
|this| {
this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
},
);
hir::ItemKind::Const(ty, generics, body_id)
}
Expand Down Expand Up @@ -448,8 +451,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
ty: &Ty,
span: Span,
body: Option<&Expr>,
impl_trait_position: ImplTraitPosition,
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(impl_trait_position));
(ty, self.lower_const_body(span, body))
}

Expand Down
92 changes: 37 additions & 55 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,6 @@ enum ImplTraitPosition {
ClosureParam,
PointerParam,
FnTraitParam,
TraitParam,
ImplParam,
ExternFnReturn,
ClosureReturn,
PointerReturn,
Expand All @@ -324,29 +322,27 @@ impl std::fmt::Display for ImplTraitPosition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name = match self {
ImplTraitPosition::Path => "paths",
ImplTraitPosition::Variable => "variable bindings",
ImplTraitPosition::Variable => "the type of variable bindings",
ImplTraitPosition::Trait => "traits",
ImplTraitPosition::AsyncBlock => "async blocks",
ImplTraitPosition::Bound => "bounds",
ImplTraitPosition::Generic => "generics",
ImplTraitPosition::ExternFnParam => "`extern fn` params",
ImplTraitPosition::ClosureParam => "closure params",
ImplTraitPosition::PointerParam => "`fn` pointer params",
ImplTraitPosition::FnTraitParam => "`Fn` trait params",
ImplTraitPosition::TraitParam => "trait method params",
ImplTraitPosition::ImplParam => "`impl` method params",
ImplTraitPosition::ExternFnParam => "`extern fn` parameters",
ImplTraitPosition::ClosureParam => "closure parameters",
ImplTraitPosition::PointerParam => "`fn` pointer parameters",
ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",
ImplTraitPosition::ExternFnReturn => "`extern fn` return types",
ImplTraitPosition::ClosureReturn => "closure return types",
ImplTraitPosition::PointerReturn => "`fn` pointer return types",
ImplTraitPosition::FnTraitReturn => "`Fn` trait return types",
ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",
ImplTraitPosition::GenericDefault => "generic parameter defaults",
ImplTraitPosition::ConstTy => "const types",
ImplTraitPosition::StaticTy => "static types",
ImplTraitPosition::AssocTy => "associated types",
ImplTraitPosition::FieldTy => "field types",
ImplTraitPosition::Cast => "cast types",
ImplTraitPosition::Cast => "cast expression types",
ImplTraitPosition::ImplSelf => "impl headers",
ImplTraitPosition::OffsetOf => "`offset_of!` params",
ImplTraitPosition::OffsetOf => "`offset_of!` parameters",
};

write!(f, "{name}")
Expand All @@ -364,19 +360,6 @@ enum FnDeclKind {
Impl,
}

impl FnDeclKind {
fn param_impl_trait_allowed(&self) -> bool {
matches!(self, FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait)
}

fn return_impl_trait_allowed(&self) -> bool {
match self {
FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true,
_ => false,
}
}
}

#[derive(Copy, Clone)]
enum AstOwner<'a> {
NonOwner,
Expand Down Expand Up @@ -1842,19 +1825,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
inputs = &inputs[..inputs.len() - 1];
}
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
let itctx = if kind.param_impl_trait_allowed() {
ImplTraitContext::Universal
} else {
ImplTraitContext::Disallowed(match kind {
FnDeclKind::Fn | FnDeclKind::Inherent => {
unreachable!("fn should allow APIT")
}
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
FnDeclKind::Trait => ImplTraitPosition::TraitParam,
FnDeclKind::Impl => ImplTraitPosition::ImplParam,
})
let itctx = match kind {
FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {
ImplTraitContext::Universal
}
FnDeclKind::ExternFn => {
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)
}
FnDeclKind::Closure => {
ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)
}
FnDeclKind::Pointer => {
ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
}
};
self.lower_ty_direct(&param.ty, &itctx)
}));
Expand All @@ -1866,26 +1849,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
None => match &decl.output {
FnRetTy::Ty(ty) => {
let context = if kind.return_impl_trait_allowed() {
let fn_def_id = self.local_def_id(fn_node_id);
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
let itctx = match kind {
FnDeclKind::Fn
| FnDeclKind::Inherent
| FnDeclKind::Trait
| FnDeclKind::Impl => ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)),
fn_kind: kind,
},
FnDeclKind::ExternFn => {
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
}
FnDeclKind::Closure => {
ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)
}
FnDeclKind::Pointer => {
ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
}
} else {
ImplTraitContext::Disallowed(match kind {
FnDeclKind::Fn
| FnDeclKind::Inherent
| FnDeclKind::Trait
| FnDeclKind::Impl => {
unreachable!("fn should allow return-position impl trait in traits")
}
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnReturn,
FnDeclKind::Closure => ImplTraitPosition::ClosureReturn,
FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
})
};
hir::FnRetTy::Return(self.lower_ty(ty, &context))
hir::FnRetTy::Return(self.lower_ty(ty, &itctx))
}
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
},
Expand Down
4 changes: 3 additions & 1 deletion tests/ui/associated-consts/issue-105330.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ LL | fn main<A: TraitWAssocConst<A=32>>() {
= note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information
= help: add `#![feature(associated_const_equality)]` to the crate attributes to enable

error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in impl headers
error[E0562]: `impl Trait` is not allowed in impl headers
--> $DIR/issue-105330.rs:6:27
|
LL | impl TraitWAssocConst for impl Demo {
| ^^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

error[E0131]: `main` function is not allowed to have generic parameters
--> $DIR/issue-105330.rs:15:8
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,20 @@ fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }

const _cdef: impl Tr1<As1: Copy> = S1;
//~^ ERROR associated type bounds are unstable
//~| ERROR `impl Trait` only allowed in function and inherent method argument and return types
//~| ERROR `impl Trait` is not allowed in const types
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
// const _cdef_dyn: &dyn Tr1<As1: Copy> = &S1;

static _sdef: impl Tr1<As1: Copy> = S1;
//~^ ERROR associated type bounds are unstable
//~| ERROR `impl Trait` only allowed in function and inherent method argument and return types
//~| ERROR `impl Trait` is not allowed in static types
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
// static _sdef_dyn: &dyn Tr1<As1: Copy> = &S1;

fn main() {
let _: impl Tr1<As1: Copy> = S1;
//~^ ERROR associated type bounds are unstable
//~| ERROR `impl Trait` only allowed in function and inherent method argument and return types
//~| ERROR `impl Trait` is not allowed in the type of variable bindings
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
// let _: &dyn Tr1<As1: Copy> = &S1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,29 @@ LL | let _: impl Tr1<As1: Copy> = S1;
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable

error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in const types
error[E0562]: `impl Trait` is not allowed in const types
--> $DIR/feature-gate-associated_type_bounds.rs:55:14
|
LL | const _cdef: impl Tr1<As1: Copy> = S1;
| ^^^^^^^^^^^^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in const types
error[E0562]: `impl Trait` is not allowed in static types
--> $DIR/feature-gate-associated_type_bounds.rs:61:15
|
LL | static _sdef: impl Tr1<As1: Copy> = S1;
| ^^^^^^^^^^^^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings
error[E0562]: `impl Trait` is not allowed in the type of variable bindings
--> $DIR/feature-gate-associated_type_bounds.rs:68:12
|
LL | let _: impl Tr1<As1: Copy> = S1;
| ^^^^^^^^^^^^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

error[E0277]: the trait bound `<<Self as _Tr3>::A as Iterator>::Item: Copy` is not satisfied
--> $DIR/feature-gate-associated_type_bounds.rs:12:28
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
fn f() -> impl Fn() -> impl Sized { || () }
//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return
//~^ ERROR `impl Trait` is not allowed in the return type of `Fn` trait bounds
fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
//~^ ERROR `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return
//~^ ERROR `impl Trait` is not allowed in the return type of `Fn` trait bounds

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types
error[E0562]: `impl Trait` is not allowed in the return type of `Fn` trait bounds
--> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:1:24
|
LL | fn f() -> impl Fn() -> impl Sized { || () }
| ^^^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
= note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information
= help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable

error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types
error[E0562]: `impl Trait` is not allowed in the return type of `Fn` trait bounds
--> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32
|
LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
| ^^^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
= note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information
= help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/issues/issue-54600.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ use std::fmt::Debug;

fn main() {
let x: Option<impl Debug> = Some(44_u32);
//~^ `impl Trait` only allowed in function and inherent method argument and return types
//~^ `impl Trait` is not allowed in the type of variable bindings
println!("{:?}", x);
}
4 changes: 3 additions & 1 deletion tests/ui/impl-trait/issues/issue-54600.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings
error[E0562]: `impl Trait` is not allowed in the type of variable bindings
--> $DIR/issue-54600.rs:4:19
|
LL | let x: Option<impl Debug> = Some(44_u32);
| ^^^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

error: aborting due to 1 previous error

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/issues/issue-54840.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ use std::ops::Add;
fn main() {
let i: i32 = 0;
let j: &impl Add = &i;
//~^ `impl Trait` only allowed in function and inherent method argument and return types
//~^ `impl Trait` is not allowed in the type of variable bindings
}
4 changes: 3 additions & 1 deletion tests/ui/impl-trait/issues/issue-54840.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings
error[E0562]: `impl Trait` is not allowed in the type of variable bindings
--> $DIR/issue-54840.rs:5:13
|
LL | let j: &impl Add = &i;
| ^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

error: aborting due to 1 previous error

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/issues/issue-58504.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ fn mk_gen() -> impl Coroutine<Return=!, Yield=()> {

fn main() {
let gens: [impl Coroutine<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ];
//~^ `impl Trait` only allowed in function and inherent method argument and return types
//~^ `impl Trait` is not allowed in the type of variable bindings
}
4 changes: 3 additions & 1 deletion tests/ui/impl-trait/issues/issue-58504.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings
error[E0562]: `impl Trait` is not allowed in the type of variable bindings
--> $DIR/issue-58504.rs:10:16
|
LL | let gens: [impl Coroutine<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

error: aborting due to 1 previous error

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/impl-trait/issues/issue-58956.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ impl Lam for B {}
pub struct Wrap<T>(T);

const _A: impl Lam = {
//~^ `impl Trait` only allowed in function and inherent method argument and return types
//~^ `impl Trait` is not allowed in const types
let x: Wrap<impl Lam> = Wrap(B);
//~^ `impl Trait` only allowed in function and inherent method argument and return types
//~^ `impl Trait` is not allowed in the type of variable bindings
x.0
};

Expand Down
8 changes: 6 additions & 2 deletions tests/ui/impl-trait/issues/issue-58956.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in const types
error[E0562]: `impl Trait` is not allowed in const types
--> $DIR/issue-58956.rs:7:11
|
LL | const _A: impl Lam = {
| ^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in variable bindings
error[E0562]: `impl Trait` is not allowed in the type of variable bindings
--> $DIR/issue-58956.rs:9:17
|
LL | let x: Wrap<impl Lam> = Wrap(B);
| ^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods

error: aborting due to 2 previous errors

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/issues/issue-70971.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn main() {
let x : (impl Copy,) = (true,);
//~^ `impl Trait` only allowed in function and inherent method argument and return types
//~^ `impl Trait` is not allowed in the type of variable bindings
}
Loading