Skip to content

Do not allow bad projection term to leak into the type checker #99890

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Item = u32>` this to
// the "projection predicate" for:
//
Expand All @@ -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((
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/associated-consts/assoc-const-ty-mismatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>();
Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/associated-consts/assoc-const-ty-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/associated-type-bounds/issue-99828.rs
Original file line number Diff line number Diff line change
@@ -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();
}
24 changes: 24 additions & 0 deletions src/test/ui/associated-type-bounds/issue-99828.stderr
Original file line number Diff line number Diff line change
@@ -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`.