From 77f7a833dd93736e899786603bbee6d28056f184 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 29 Jul 2022 05:48:40 +0000 Subject: [PATCH] Do not allow bad projection term to leak into the type checker --- compiler/rustc_typeck/src/astconv/mod.rs | 18 ++++++++++---- .../assoc-const-ty-mismatch.rs | 4 ++-- .../assoc-const-ty-mismatch.stderr | 8 +++---- .../ui/associated-type-bounds/issue-99828.rs | 11 +++++++++ .../associated-type-bounds/issue-99828.stderr | 24 +++++++++++++++++++ 5 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/associated-type-bounds/issue-99828.rs create mode 100644 src/test/ui/associated-type-bounds/issue-99828.stderr diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 08e8e6f7d0f..444f0fdd45a 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1234,7 +1234,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } match binding.kind { - ConvertedBindingKind::Equality(term) => { + ConvertedBindingKind::Equality(mut term) => { // "Desugar" a constraint like `T: Iterator` this to // the "projection predicate" for: // @@ -1245,18 +1245,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (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(( diff --git a/src/test/ui/associated-consts/assoc-const-ty-mismatch.rs b/src/test/ui/associated-consts/assoc-const-ty-mismatch.rs index c3293156345..c5d78469e95 100644 --- a/src/test/ui/associated-consts/assoc-const-ty-mismatch.rs +++ b/src/test/ui/associated-consts/assoc-const-ty-mismatch.rs @@ -21,9 +21,9 @@ impl FooTy for Bar { fn foo>() {} -//~^ ERROR mismatch in +//~^ ERROR expected associated constant bound, found type fn foo2>() {} -//~^ ERROR mismatch in +//~^ ERROR expected associated type bound, found constant fn main() { foo::(); diff --git a/src/test/ui/associated-consts/assoc-const-ty-mismatch.stderr b/src/test/ui/associated-consts/assoc-const-ty-mismatch.stderr index 58a8aceca2f..11198729e38 100644 --- a/src/test/ui/associated-consts/assoc-const-ty-mismatch.stderr +++ b/src/test/ui/associated-consts/assoc-const-ty-mismatch.stderr @@ -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>() {} | ^^^^^^^ | -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>() {} | ^^^^^^^^ | -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 index 00000000000..7b711283f5b --- /dev/null +++ b/src/test/ui/associated-type-bounds/issue-99828.rs @@ -0,0 +1,11 @@ +fn get_iter(vec: &[i32]) -> impl Iterator + '_ { + //~^ 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 index 00000000000..1c20ead0556 --- /dev/null +++ b/src/test/ui/associated-type-bounds/issue-99828.stderr @@ -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 + '_ { + | ^^^^^^^^^ + | + = note: see issue #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 + '_ { + | ^^^^^^^^^ + | +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`.