Skip to content

Commit 6e6d8a1

Browse files
Add a helpful suggestion
1 parent 012bc48 commit 6e6d8a1

File tree

7 files changed

+58
-50
lines changed

7 files changed

+58
-50
lines changed

compiler/rustc_ast_lowering/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ast_lowering_argument = argument
1010
1111
ast_lowering_assoc_ty_binding_in_dyn =
1212
associated type bounds are not allowed in `dyn` types
13+
.suggestion = use `impl Trait` to introduce a type instead
1314
1415
ast_lowering_assoc_ty_parentheses =
1516
parenthesized generic arguments cannot be used in associated type constraints

compiler/rustc_ast_lowering/src/errors.rs

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ pub struct MisplacedImplTrait<'a> {
9898
pub struct MisplacedAssocTyBinding {
9999
#[primary_span]
100100
pub span: Span,
101+
#[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")]
102+
pub suggestion: Option<Span>,
101103
}
102104

103105
#[derive(Diagnostic, Clone, Copy)]

compiler/rustc_ast_lowering/src/lib.rs

+45-26
Original file line numberDiff line numberDiff line change
@@ -1088,32 +1088,50 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10881088
AssocConstraintKind::Bound { bounds } => {
10891089
enum DesugarKind {
10901090
ImplTrait,
1091-
Error,
1091+
Error(Option<Span>),
10921092
Bound,
10931093
}
10941094

10951095
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
1096-
let desugar_kind = match itctx {
1097-
_ if self.is_in_dyn_type => DesugarKind::Error,
1098-
1099-
// We are in the return position:
1100-
//
1101-
// fn foo() -> impl Iterator<Item: Debug>
1102-
//
1103-
// so desugar to
1104-
//
1105-
// fn foo() -> impl Iterator<Item = impl Debug>
1106-
ImplTraitContext::ReturnPositionOpaqueTy { .. }
1107-
| ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait,
1108-
1109-
// We are in the parameter position, but not within a dyn type:
1110-
//
1111-
// fn foo(x: impl Iterator<Item: Debug>)
1112-
//
1113-
// so we leave it as is and this gets expanded in astconv to a bound like
1114-
// `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
1115-
// `impl Iterator`.
1116-
_ => DesugarKind::Bound,
1096+
let desugar_kind = if self.is_in_dyn_type {
1097+
match itctx {
1098+
ImplTraitContext::ReturnPositionOpaqueTy { .. }
1099+
| ImplTraitContext::TypeAliasesOpaqueTy { .. }
1100+
| ImplTraitContext::Universal => {
1101+
let bound_end_span = constraint
1102+
.gen_args
1103+
.as_ref()
1104+
.map_or(constraint.ident.span, |args| args.span());
1105+
let colon_span = if bound_end_span.eq_ctxt(constraint.span) {
1106+
Some(self.tcx.sess.source_map().next_point(bound_end_span))
1107+
} else {
1108+
None
1109+
};
1110+
DesugarKind::Error(colon_span)
1111+
}
1112+
_ => DesugarKind::Error(None),
1113+
}
1114+
} else {
1115+
match itctx {
1116+
// We are in the return position:
1117+
//
1118+
// fn foo() -> impl Iterator<Item: Debug>
1119+
//
1120+
// so desugar to
1121+
//
1122+
// fn foo() -> impl Iterator<Item = impl Debug>
1123+
ImplTraitContext::ReturnPositionOpaqueTy { .. }
1124+
| ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait,
1125+
1126+
// We are in the parameter position, but not within a dyn type:
1127+
//
1128+
// fn foo(x: impl Iterator<Item: Debug>)
1129+
//
1130+
// so we leave it as is and this gets expanded in astconv to a bound like
1131+
// `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
1132+
// `impl Iterator`.
1133+
_ => DesugarKind::Bound,
1134+
}
11171135
};
11181136

11191137
match desugar_kind {
@@ -1150,10 +1168,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11501168

11511169
hir::TypeBindingKind::Constraint { bounds }
11521170
}
1153-
DesugarKind::Error => {
1154-
let guar = self
1155-
.dcx()
1156-
.emit_err(errors::MisplacedAssocTyBinding { span: constraint.span });
1171+
DesugarKind::Error(suggestion) => {
1172+
let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
1173+
span: constraint.span,
1174+
suggestion,
1175+
});
11571176
let err_ty =
11581177
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
11591178
hir::TypeBindingKind::Equality { term: err_ty.into() }

tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ error: associated type bounds are not allowed in `dyn` types
33
|
44
LL | type Out = Box<dyn Bar<Assoc: Copy>>;
55
| ^^^^^^^^^^^
6+
|
7+
help: use `impl Trait` to introduce a type instead
8+
|
9+
LL | type Out = Box<dyn Bar<Assoc = impl Copy>>;
10+
| ~~~~~~
611

712
error: aborting due to 1 previous error
813

tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr

-12
This file was deleted.

tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr

-12
This file was deleted.

tests/ui/associated-type-bounds/elision.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ error: associated type bounds are not allowed in `dyn` types
1515
|
1616
LL | fn f(x: &mut dyn Iterator<Item: Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
|
19+
help: use `impl Trait` to introduce a type instead
20+
|
21+
LL | fn f(x: &mut dyn Iterator<Item = impl Iterator<Item = &'_ ()>>) -> Option<&'_ ()> { x.next() }
22+
| ~~~~~~
1823

1924
error: aborting due to 2 previous errors
2025

0 commit comments

Comments
 (0)