]> git.lizzy.rs Git - rust.git/commitdiff
Do not allow bad projection term to leak into the type checker
authorMichael Goulet <michael@errs.io>
Fri, 29 Jul 2022 05:48:40 +0000 (05:48 +0000)
committerMichael Goulet <michael@errs.io>
Fri, 29 Jul 2022 05:48:40 +0000 (05:48 +0000)
compiler/rustc_typeck/src/astconv/mod.rs
src/test/ui/associated-consts/assoc-const-ty-mismatch.rs
src/test/ui/associated-consts/assoc-const-ty-mismatch.stderr
src/test/ui/associated-type-bounds/issue-99828.rs [new file with mode: 0644]
src/test/ui/associated-type-bounds/issue-99828.stderr [new file with mode: 0644]

index 08e8e6f7d0f402d18d9273702e983ffab5324733..444f0fdd45a83faa289223dab995158ecc729f8c 100644 (file)
@@ -1234,7 +1234,7 @@ fn add_predicates_for_ast_type_binding(
         }
 
         match binding.kind {
-            ConvertedBindingKind::Equality(term) => {
+            ConvertedBindingKind::Equality(mut term) => {
                 // "Desugar" a constraint like `T: Iterator<Item = u32>` this to
                 // the "projection predicate" for:
                 //
@@ -1245,18 +1245,28 @@ fn add_predicates_for_ast_type_binding(
                     (hir::def::DefKind::AssocTy, ty::Term::Ty(_))
                     | (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (),
                     (_, _) => {
-                        let got = if let ty::Term::Ty(_) = term { "type" } else { "const" };
+                        let got = if let ty::Term::Ty(_) = term { "type" } else { "constant" };
                         let expected = def_kind.descr(assoc_item_def_id);
                         tcx.sess
                             .struct_span_err(
                                 binding.span,
-                                &format!("mismatch in bind of {expected}, got {got}"),
+                                &format!("expected {expected} bound, found {got}"),
                             )
                             .span_note(
                                 tcx.def_span(assoc_item_def_id),
-                                &format!("{expected} defined here does not match {got}"),
+                                &format!("{expected} defined here"),
                             )
                             .emit();
+                        term = match def_kind {
+                            hir::def::DefKind::AssocTy => tcx.ty_error().into(),
+                            hir::def::DefKind::AssocConst => tcx
+                                .const_error(
+                                    tcx.bound_type_of(assoc_item_def_id)
+                                        .subst(tcx, projection_ty.skip_binder().substs),
+                                )
+                                .into(),
+                            _ => unreachable!(),
+                        };
                     }
                 }
                 bounds.projection_bounds.push((
index c3293156345a79bcadcb4aeaf150400e9bb89704..c5d78469e955ef1abaaf952e1e297e3066467f1b 100644 (file)
@@ -21,9 +21,9 @@ impl FooTy for Bar {
 
 
 fn foo<F: Foo<N=usize>>() {}
-//~^ ERROR mismatch in
+//~^ ERROR expected associated constant bound, found type
 fn foo2<F: FooTy<T=3usize>>() {}
-//~^ ERROR mismatch in
+//~^ ERROR expected associated type bound, found constant
 
 fn main() {
   foo::<Bar>();
index 58a8aceca2f24fc6d83c510fd3c91bf56a04e033..11198729e38cbd2d5d3c1439451a417c0d7ec72a 100644 (file)
@@ -1,22 +1,22 @@
-error: mismatch in bind of associated constant, got type
+error: expected associated constant bound, found type
   --> $DIR/assoc-const-ty-mismatch.rs:23:15
    |
 LL | fn foo<F: Foo<N=usize>>() {}
    |               ^^^^^^^
    |
-note: associated constant defined here does not match type
+note: associated constant defined here
   --> $DIR/assoc-const-ty-mismatch.rs:5:3
    |
 LL |   const N: usize;
    |   ^^^^^^^^^^^^^^
 
-error: mismatch in bind of associated type, got const
+error: expected associated type bound, found constant
   --> $DIR/assoc-const-ty-mismatch.rs:25:18
    |
 LL | fn foo2<F: FooTy<T=3usize>>() {}
    |                  ^^^^^^^^
    |
-note: associated type defined here does not match const
+note: associated type defined here
   --> $DIR/assoc-const-ty-mismatch.rs:9:3
    |
 LL |   type T;
diff --git a/src/test/ui/associated-type-bounds/issue-99828.rs b/src/test/ui/associated-type-bounds/issue-99828.rs
new file mode 100644 (file)
index 0000000..7b71128
--- /dev/null
@@ -0,0 +1,11 @@
+fn get_iter(vec: &[i32]) -> impl Iterator<Item = {}> + '_ {
+    //~^ ERROR expected associated type bound, found constant
+    //~| ERROR associated const equality is incomplete
+    vec.iter()
+}
+
+fn main() {
+    let vec = Vec::new();
+    let mut iter = get_iter(&vec);
+    iter.next();
+}
diff --git a/src/test/ui/associated-type-bounds/issue-99828.stderr b/src/test/ui/associated-type-bounds/issue-99828.stderr
new file mode 100644 (file)
index 0000000..1c20ead
--- /dev/null
@@ -0,0 +1,24 @@
+error[E0658]: associated const equality is incomplete
+  --> $DIR/issue-99828.rs:1:43
+   |
+LL | fn get_iter(vec: &[i32]) -> impl Iterator<Item = {}> + '_ {
+   |                                           ^^^^^^^^^
+   |
+   = 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: expected associated type bound, found constant
+  --> $DIR/issue-99828.rs:1:43
+   |
+LL | fn get_iter(vec: &[i32]) -> impl Iterator<Item = {}> + '_ {
+   |                                           ^^^^^^^^^
+   |
+note: associated type defined here
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+   |
+LL |     type Item;
+   |     ^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.