Skip to content
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
26 changes: 24 additions & 2 deletions compiler/rustc_type_ir/src/relate/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,31 @@ where
panic!("We do not expect to encounter `Fresh` variables in the new solver")
}

(_, ty::Alias(..)) | (ty::Alias(..), _) if infcx.next_trait_solver() => {
(other, ty::Alias(..)) | (ty::Alias(..), other) if infcx.next_trait_solver() => {
match relation.structurally_relate_aliases() {
StructurallyRelateAliases::Yes => structurally_relate_tys(relation, a, b),
StructurallyRelateAliases::Yes => match other {
ty::Infer(infer_ty) => match infer_ty {
// Normally, we shouldn't be combining an infer ty with an alias here. But
// when we evaluate a `Projection(assoc_ty, expected)` goal, we normalize
// the projection term and structurally equate it with the expected term. If
// the normalized term is an alias type and the expected term is a ty var,
// the ty var just instantiated with the alias type without combining them.
// However, if the expected term is either an int var or a float var, e.g.,
// when the expected term is an int literal that only can be fully inferred
// after the fallback, they are passed to this function because int/float
// vars can't be instantiated. As we can't structurally relate infer ty with
// another type, we just error them out here instead.
ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(_) => {
Err(TypeError::Sorts(ExpectedFound::new(a, b)))
}

ty::InferTy::TyVar(_)
| ty::InferTy::FreshTy(_)
| ty::InferTy::FreshIntTy(_)
| ty::InferTy::FreshFloatTy(_) => unreachable!(),
},
_ => structurally_relate_tys(relation, a, b),
},
StructurallyRelateAliases::No => {
relation.register_alias_relate_predicate(a, b);
Ok(a)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
//@ check-pass

// Regression test for <https://github.com/rust-lang/rust/issues/158064>

trait Trait {
fn bar() -> impl Clone {
1
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0271]: expected `foo` to return `{integer}`, but it returns `impl Sized`
--> $DIR/normalize-assoc-ty-expected-int-var-no-ice-2.rs:13:10
|
LL | fn foo() -> impl Sized {}
| ---------- the found opaque type
...
LL | proj(x, 1);
| ---- ^ expected integer, found opaque type
| |
| required by a bound introduced by this call
|
= note: expected type `{integer}`
found opaque type `impl Sized`
note: required by a bound in `proj`
--> $DIR/normalize-assoc-ty-expected-int-var-no-ice-2.rs:9:24
|
LL | fn proj<T: FnOnce() -> U, U>(x: Option<T>, y: U) {}
| ^ required by this bound in `proj`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0271`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0271]: type mismatch resolving `<fn() -> impl Sized {foo} as FnOnce<()>>::Output == {integer}`
--> $DIR/normalize-assoc-ty-expected-int-var-no-ice-2.rs:13:10
|
LL | proj(x, 1);
| ---- ^ types differ
| |
| required by a bound introduced by this call
|
note: required by a bound in `proj`
--> $DIR/normalize-assoc-ty-expected-int-var-no-ice-2.rs:9:24
|
LL | fn proj<T: FnOnce() -> U, U>(x: Option<T>, y: U) {}
| ^ required by this bound in `proj`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0271`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

// Regression test for <https://github.com/rust-lang/rust/issues/158064>

fn foo() -> impl Sized {}

fn proj<T: FnOnce() -> U, U>(x: Option<T>, y: U) {}

fn main() {
let mut x = None;
proj(x, 1);
//[current]~^ ERROR: expected `foo` to return `{integer}`, but it returns `impl Sized`
//[next]~^^ ERROR: type mismatch resolving `<fn() -> impl Sized {foo} as FnOnce<()>>::Output == {integer}`
x = Some(foo);
}
Loading