Suppress duplicated errors for associated type bounds in object types
This commit is contained in:
@@ -1011,8 +1011,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
hir::TypeBindingKind::Equality { term }
|
||||
}
|
||||
AssocConstraintKind::Bound { bounds } => {
|
||||
enum DesugarKind<'a> {
|
||||
ImplTrait,
|
||||
Error(&'a ImplTraitPosition),
|
||||
Bound,
|
||||
}
|
||||
|
||||
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
|
||||
let (desugar_to_impl_trait, itctx) = match itctx {
|
||||
let desugar_kind = match itctx {
|
||||
// We are in the return position:
|
||||
//
|
||||
// fn foo() -> impl Iterator<Item: Debug>
|
||||
@@ -1021,7 +1027,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
//
|
||||
// fn foo() -> impl Iterator<Item = impl Debug>
|
||||
ImplTraitContext::ReturnPositionOpaqueTy { .. }
|
||||
| ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx),
|
||||
| ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait,
|
||||
|
||||
// We are in the argument position, but within a dyn type:
|
||||
//
|
||||
@@ -1030,7 +1036,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// so desugar to
|
||||
//
|
||||
// fn foo(x: dyn Iterator<Item = impl Debug>)
|
||||
ImplTraitContext::Universal if self.is_in_dyn_type => (true, itctx),
|
||||
ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait,
|
||||
|
||||
// In `type Foo = dyn Iterator<Item: Debug>` we desugar to
|
||||
// `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
|
||||
@@ -1039,11 +1045,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
//
|
||||
// FIXME: this is only needed until `impl Trait` is allowed in type aliases.
|
||||
ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => {
|
||||
self.tcx.sess.emit_err(errors::MisplacedAssocTyBinding {
|
||||
span: constraint.span,
|
||||
position: DiagnosticArgFromDisplay(position),
|
||||
});
|
||||
(false, itctx)
|
||||
DesugarKind::Error(position)
|
||||
}
|
||||
|
||||
// We are in the parameter position, but not within a dyn type:
|
||||
@@ -1053,35 +1055,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// so we leave it as is and this gets expanded in astconv to a bound like
|
||||
// `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
|
||||
// `impl Iterator`.
|
||||
_ => (false, itctx),
|
||||
_ => DesugarKind::Bound,
|
||||
};
|
||||
|
||||
if desugar_to_impl_trait {
|
||||
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
|
||||
// constructing the HIR for `impl bounds...` and then lowering that.
|
||||
match desugar_kind {
|
||||
DesugarKind::ImplTrait => {
|
||||
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
|
||||
// constructing the HIR for `impl bounds...` and then lowering that.
|
||||
|
||||
let impl_trait_node_id = self.next_node_id();
|
||||
let impl_trait_node_id = self.next_node_id();
|
||||
|
||||
self.with_dyn_type_scope(false, |this| {
|
||||
let node_id = this.next_node_id();
|
||||
let ty = this.lower_ty(
|
||||
&Ty {
|
||||
id: node_id,
|
||||
kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
|
||||
span: this.lower_span(constraint.span),
|
||||
tokens: None,
|
||||
},
|
||||
itctx,
|
||||
);
|
||||
self.with_dyn_type_scope(false, |this| {
|
||||
let node_id = this.next_node_id();
|
||||
let ty = this.lower_ty(
|
||||
&Ty {
|
||||
id: node_id,
|
||||
kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
|
||||
span: this.lower_span(constraint.span),
|
||||
tokens: None,
|
||||
},
|
||||
itctx,
|
||||
);
|
||||
|
||||
hir::TypeBindingKind::Equality { term: ty.into() }
|
||||
})
|
||||
} else {
|
||||
// Desugar `AssocTy: Bounds` into a type binding where the
|
||||
// later desugars into a trait predicate.
|
||||
let bounds = self.lower_param_bounds(bounds, itctx);
|
||||
hir::TypeBindingKind::Equality { term: ty.into() }
|
||||
})
|
||||
}
|
||||
DesugarKind::Bound => {
|
||||
// Desugar `AssocTy: Bounds` into a type binding where the
|
||||
// later desugars into a trait predicate.
|
||||
let bounds = self.lower_param_bounds(bounds, itctx);
|
||||
|
||||
hir::TypeBindingKind::Constraint { bounds }
|
||||
hir::TypeBindingKind::Constraint { bounds }
|
||||
}
|
||||
DesugarKind::Error(position) => {
|
||||
self.tcx.sess.emit_err(errors::MisplacedAssocTyBinding {
|
||||
span: constraint.span,
|
||||
position: DiagnosticArgFromDisplay(position),
|
||||
});
|
||||
let err_ty = &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err));
|
||||
hir::TypeBindingKind::Equality { term: err_ty.into() }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user