about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-02-14 20:07:33 +0000
committerMichael Goulet <michael@errs.io>2023-02-22 21:52:26 +0000
commitdeb135748d8489118e968b229c5c92d4fa18a1cf (patch)
treefd180497b63ca09f9fdd527f1838dc57f1f2dcff
parente7c490892f440afb1e34b3c2315aca04f51cd070 (diff)
downloadrust-deb135748d8489118e968b229c5c92d4fa18a1cf.tar.gz
rust-deb135748d8489118e968b229c5c92d4fa18a1cf.zip
Suppress duplicated errors for associated type bounds in object types
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs79
-rw-r--r--tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs1
-rw-r--r--tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr12
-rw-r--r--tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs1
-rw-r--r--tests/ui/associated-type-bounds/inside-adt.rs9
-rw-r--r--tests/ui/associated-type-bounds/inside-adt.stderr91
6 files changed, 56 insertions, 137 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 60391f77449..9faf112f4a1 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -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.
-
-                    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,
-                        );
+                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.
 
-                        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);
+                        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,
+                            );
 
-                    hir::TypeBindingKind::Constraint { bounds }
+                            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 }
+                    }
+                    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() }
+                    }
                 }
             }
         };
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs
index 2d04f6fc452..8cab1f66c27 100644
--- a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs
+++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs
@@ -8,7 +8,6 @@ fn f()
 where
     dyn for<'j> B<AssocType: 'j>:,
     //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-    //~| ERROR the value of the associated type `AssocType` (from trait `B`) must be specified
 {
 }
 
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr
index ffba044e7e7..fdc221eeda2 100644
--- a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr
+++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr
@@ -4,15 +4,5 @@ error: associated type bounds are only allowed in where clauses and function sig
 LL |     dyn for<'j> B<AssocType: 'j>:,
    |                   ^^^^^^^^^^^^^
 
-error[E0191]: the value of the associated type `AssocType` (from trait `B`) must be specified
-  --> $DIR/bad-universal-in-dyn-in-where-clause.rs:9:9
-   |
-LL |     type AssocType;
-   |     -------------- `AssocType` defined here
-...
-LL |     dyn for<'j> B<AssocType: 'j>:,
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `for<'j> B<AssocType: 'j, AssocType = Type>`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0191`.
diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs
index dd59dbd243e..1d5d181efcc 100644
--- a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs
+++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs
@@ -9,6 +9,5 @@ trait Trait2 {}
 // It's not possible to insert a universal `impl Trait` here!
 impl dyn Trait<Item: Trait2> {}
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Trait`) must be specified
 
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/inside-adt.rs b/tests/ui/associated-type-bounds/inside-adt.rs
index 70a30287092..057966941dc 100644
--- a/tests/ui/associated-type-bounds/inside-adt.rs
+++ b/tests/ui/associated-type-bounds/inside-adt.rs
@@ -4,32 +4,23 @@ use std::mem::ManuallyDrop;
 
 struct S1 { f: dyn Iterator<Item: Copy> }
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
 struct S2 { f: Box<dyn Iterator<Item: Copy>> }
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
 struct S3 { f: dyn Iterator<Item: 'static> }
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
 
 enum E1 { V(dyn Iterator<Item: Copy>) }
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
 enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
 enum E3 { V(dyn Iterator<Item: 'static>) }
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
 
 union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
 union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
 union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
 //~^ ERROR associated type bounds are only allowed in where clauses and function signatures
-//~| ERROR the value of the associated type `Item` (from trait `Iterator`) must be specified
 
 fn main() {}
diff --git a/tests/ui/associated-type-bounds/inside-adt.stderr b/tests/ui/associated-type-bounds/inside-adt.stderr
index e1d35bd9c32..f631ad5b78a 100644
--- a/tests/ui/associated-type-bounds/inside-adt.stderr
+++ b/tests/ui/associated-type-bounds/inside-adt.stderr
@@ -5,125 +5,52 @@ LL | struct S1 { f: dyn Iterator<Item: Copy> }
    |                             ^^^^^^^^^^
 
 error: associated type bounds are only allowed in where clauses and function signatures, not in field type
-  --> $DIR/inside-adt.rs:8:33
+  --> $DIR/inside-adt.rs:7:33
    |
 LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> }
    |                                 ^^^^^^^^^^
 
 error: associated type bounds are only allowed in where clauses and function signatures, not in field type
-  --> $DIR/inside-adt.rs:11:29
+  --> $DIR/inside-adt.rs:9:29
    |
 LL | struct S3 { f: dyn Iterator<Item: 'static> }
    |                             ^^^^^^^^^^^^^
 
 error: associated type bounds are only allowed in where clauses and function signatures, not in field type
-  --> $DIR/inside-adt.rs:15:26
+  --> $DIR/inside-adt.rs:12:26
    |
 LL | enum E1 { V(dyn Iterator<Item: Copy>) }
    |                          ^^^^^^^^^^
 
 error: associated type bounds are only allowed in where clauses and function signatures, not in field type
-  --> $DIR/inside-adt.rs:18:30
+  --> $DIR/inside-adt.rs:14:30
    |
 LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
    |                              ^^^^^^^^^^
 
 error: associated type bounds are only allowed in where clauses and function signatures, not in field type
-  --> $DIR/inside-adt.rs:21:26
+  --> $DIR/inside-adt.rs:16:26
    |
 LL | enum E3 { V(dyn Iterator<Item: 'static>) }
    |                          ^^^^^^^^^^^^^
 
 error: associated type bounds are only allowed in where clauses and function signatures, not in field type
-  --> $DIR/inside-adt.rs:25:41
+  --> $DIR/inside-adt.rs:19:41
    |
 LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
    |                                         ^^^^^^^^^^
 
 error: associated type bounds are only allowed in where clauses and function signatures, not in field type
-  --> $DIR/inside-adt.rs:28:45
+  --> $DIR/inside-adt.rs:21:45
    |
 LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
    |                                             ^^^^^^^^^^
 
 error: associated type bounds are only allowed in where clauses and function signatures, not in field type
-  --> $DIR/inside-adt.rs:31:41
+  --> $DIR/inside-adt.rs:23:41
    |
 LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
    |                                         ^^^^^^^^^^^^^
 
-error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
-  --> $DIR/inside-adt.rs:5:20
-   |
-LL | struct S1 { f: dyn Iterator<Item: Copy> }
-   |                    ^^^^^^^^^^^^^^^^^^^^
-   |                    |
-   |                    associated type `Item` must be specified
-   |                    help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
-
-error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
-  --> $DIR/inside-adt.rs:8:24
-   |
-LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> }
-   |                        ^^^^^^^^^^^^^^^^^^^^
-   |                        |
-   |                        associated type `Item` must be specified
-   |                        help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
-
-error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
-  --> $DIR/inside-adt.rs:11:20
-   |
-LL | struct S3 { f: dyn Iterator<Item: 'static> }
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Iterator<Item: 'static, Item = Type>`
-
-error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
-  --> $DIR/inside-adt.rs:15:17
-   |
-LL | enum E1 { V(dyn Iterator<Item: Copy>) }
-   |                 ^^^^^^^^^^^^^^^^^^^^
-   |                 |
-   |                 associated type `Item` must be specified
-   |                 help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
-
-error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
-  --> $DIR/inside-adt.rs:18:21
-   |
-LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) }
-   |                     ^^^^^^^^^^^^^^^^^^^^
-   |                     |
-   |                     associated type `Item` must be specified
-   |                     help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
-
-error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
-  --> $DIR/inside-adt.rs:21:17
-   |
-LL | enum E3 { V(dyn Iterator<Item: 'static>) }
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Iterator<Item: 'static, Item = Type>`
-
-error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
-  --> $DIR/inside-adt.rs:25:32
-   |
-LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> }
-   |                                ^^^^^^^^^^^^^^^^^^^^
-   |                                |
-   |                                associated type `Item` must be specified
-   |                                help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
-
-error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
-  --> $DIR/inside-adt.rs:28:36
-   |
-LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> }
-   |                                    ^^^^^^^^^^^^^^^^^^^^
-   |                                    |
-   |                                    associated type `Item` must be specified
-   |                                    help: specify the associated types: `Iterator<Item: Copy, Item = Type>`
-
-error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
-  --> $DIR/inside-adt.rs:31:32
-   |
-LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> }
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Iterator<Item: 'static, Item = Type>`
-
-error: aborting due to 18 previous errors
+error: aborting due to 9 previous errors
 
-For more information about this error, try `rustc --explain E0191`.