Description
the following snippet is ambig with the new solver and compiles with old
use num_traits::Zero;
use nalgebra::{DimName, Scalar, U1, Matrix};
use nalgebra::DefaultAllocator;
use nalgebra::allocator::Allocator;
type Alias<T, D> = Matrix<T, D, U1, <DefaultAllocator as Allocator<D>>::Buffer<T>>;
fn foo<T: Scalar + Zero, D: DimName>() -> Matrix<T, D, U1, <DefaultAllocator as Allocator<D>>::Buffer<T>>
where
DefaultAllocator: Allocator<D>,
{
Matrix::<_, _, U1, <DefaultAllocator as Allocator<_>>::Buffer<T>>::from_element(T::zero()) // works
// Alias::<T, _>::from_element(T::zero()) // error
}
minimizing this to not depend on nalgebra results in the following
trait Constrain<T> {
type Assoc;
}
impl<T> Constrain<T> for () {
type Assoc = ();
}
struct Foo<T, U = <() as Constrain<T>>::Assoc>(T, U);
impl<T: Copy> Foo<T> {
fn foo() {}
}
struct B;
impl Foo<B> {
fn foo() {}
}
type Alias<T> = Foo<T>;
fn via_guidance<T: Copy>()
where
(): Constrain<T>,
{
Alias::foo();
}
this errors with the following with the new solver
error[E0034]: multiple applicable items in scope
--> src/lib.rs:26:10
|
26 | Foo::foo();
| ^^^ multiple `foo` found
|
note: candidate #1 is defined in an impl for the type `Foo<B>`
--> src/lib.rs:17:5
|
17 | fn foo() {}
| ^^^^^^^^
note: candidate #2 is defined in an impl for the type `Foo<T>`
--> src/lib.rs:13:5
|
13 | fn foo() {}
| ^^^^^^^^
This compiles in the old solver as Alias
expands to Foo<?x, <() as Constrain<?x>>::Assoc>
. Normalizing <() as Constrain<?x>>::Assoc
constrains ?x
to T
, at which point method selection has a unique candidate.
In the new solver we never try to normalize <() as Constrain<?x>>::Assoc
, causing ?x
to remain ambiguous at this point, resulting in an ambiguity error during method selection.
Subtle: using Foo
instead of Alias
errors on stable as well, as it gets lowered to Foo<?x, ?y>
instead without using the default argument. Foo::<_>
also gets lowered to Foo<?x, ?y>
. We only use default arguments if infer_args
is set to false
during ast lowering in the lowerer. I don't understand why that is the case tbh 🤷
Metadata
Metadata
Assignees
Labels
Type
Projects
Status