Skip to content
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

Poor interaction between int fallback and other flow of type information #23545

Open
aturon opened this issue Mar 20, 2015 · 8 comments
Open
Labels
A-inference Area: Type inference A-type-system Area: Type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@aturon
Copy link
Member

aturon commented Mar 20, 2015

A reduced example:

use std::ops::Shl;

struct Foo<T>(T);

impl<T> Shl<usize> for Foo<T> {
    type Output = Foo<T>;
    fn shl(self, _: usize) -> Foo<T> { self }
}

impl<T> Shl<i32> for Foo<T> {
    type Output = Foo<T>;
    fn shl(self, _: i32) -> Foo<T> { self }
}

fn main() {
    let _ = Foo(0u32) << 2; // works fine

    let _ = (Foo(0u32) << 2).0; // does not work

    let x = Foo(0u32) << 2; // does not work
    let _ = x.0;

    let x: Foo<u32> = Foo(0u32) << 2; // works
    let _ = x.0;
}

generates the following error:

<anon>:18:13: 18:31 error: the type of this value must be known in this context
<anon>:18     let _ = (Foo(0u32) << 2).0; // does not work
                      ^~~~~~~~~~~~~~~~~~
<anon>:21:13: 21:16 error: the type of this value must be known in this context
<anon>:21     let _ = x.0;
                      ^~~

I suspect what is happening here is that the fallback isn't being triggered early enough -- in particular, before the projection is generating the error. Note that the same problem occurs with a normal struct.

(This may be one reason that Shl/Shr are only implemented on usize for Wrapping<T>.)

@aturon
Copy link
Member Author

aturon commented Mar 20, 2015

cc @nikomatsakis

@aturon aturon added the A-type-system Area: Type system label Mar 20, 2015
@aturon
Copy link
Member Author

aturon commented Mar 20, 2015

Another example, with the new inherent methods:

fn main() {
    let _ = 32_u8.count_zeros();  // works
    let _ = 32.count_zeros(); // does not work
}

@pnkfelix

This comment has been minimized.

@nikomatsakis
Copy link
Contributor

These examples so far seem to be "working as designed". That is, we do not do fallback early in the cycle, but only after we've gotten to the end, and we currently do require some type-directed actions (like field access) to have resolved types, for better or worse. We could do work on the type system to make it less... eager. In other words, it should generate deferred constraints and try to solve them. That is sort of the general fix to this problem I guess.

@bluss
Copy link
Member

bluss commented May 3, 2015

This code says

let x = 1.;
let y = x.min(2.); // error: type `_` does not implement any method in scope named `min`

The last line puzzled me the most here. I went about to tell Rust a type to use, still no dice.

[1., 2., 3.].iter().fold(1./0., |acc, &x| f32::min(acc, x)); // OK
[1., 2., 3.].iter().fold(1./0., |acc, &x| acc.min(x)); // error: type `_` does not implement any method in scope named `min`
[1.0_f32, 2., 3.].iter().fold(1./0., |acc, &x| acc.min(x)); // error: type `_` does not implement any method in scope named `min`

@eddyb
Copy link
Member

eddyb commented Jan 5, 2016

@nikomatsakis The interesting thing about 32.count_zeros() is that it would totally work if count_zeroes came from a trait because we coalesce those into one signature (the trait's view of the method).

Couldn't we do something similar for an inherent method present on multiple integer types?

I guess we would need a way to represent <_>::count_zeroes, not fully selected, which we currently don't have (trait methods are easy because they have HIR nodes and DefIds).

@nikomatsakis
Copy link
Contributor

On Tue, Jan 05, 2016 at 02:27:31PM -0800, Eduard-Mihai Burtescu wrote:

@nikomatsakis The interesting thing about 32.count_zeros() is that it would totally work if count_zeroes came from a trait because we coalesce those into one signature (the trait's view of the method).

Couldn't we do something similar for an inherent method present on multiple integer types?

Possibly, but it'd be very hard-coded.

I guess we would need a way to represent <_>::count_zeroes, not fully selected, which we currently don't have (trait methods are easy because they have HIR nodes and DefIds).

Yes. I suspect this is eminently doable. I've been thinking about it
in the context of wanting to do a ground-up rewrite of typeck, but of
course that's an ambitious (and perhaps foolhardy) way of going about
things, perhaps I should look to see if we could do something more
targeted. The current setup is certainly a common source of annoyance.

@steveklabnik
Copy link
Member

Triage: no change

@Noratrieb Noratrieb added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue. labels Apr 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inference Area: Type inference A-type-system Area: Type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants