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

Rewrite how trait-impl matching works in typeck #3742

Closed
nikomatsakis opened this issue Oct 12, 2012 · 10 comments
Closed

Rewrite how trait-impl matching works in typeck #3742

nikomatsakis opened this issue Oct 12, 2012 · 10 comments
Assignees
Labels
A-type-system Area: Type system C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@nikomatsakis
Copy link
Contributor

Right now, we have this hokey thing where it walks the tree at the end, but sometimes (to help with inference) does resolution eagerly, and it's all a big mess. Besides being hard to understand and inefficient, this also means that inference often fails where it could succeed. An example is the overloading example I gave in my blog post, where the result type often fails to be inferred (at least according to some folk on IRC, I haven't experimented much with this myself, so I don't have a precise test case).

I want to have it work something like this:

  • There is a list in the fn_ctxt of pending type-trait pairs that need to be resolved
  • We add new pairs to this list as we do our type check, assigning each pair an index.
  • When we add a new pair to the list, we can try to eagerly resolve it at that time, which helps with type inference
  • Actually, we are free to try and resolve whenever we like, so we can even wait to try and resolve when we encounter types whose structure is not known but needs to be
  • At the end, we walk the list and make sure all pairs are resolvable

These pairs more-or-less correspond to Haskell's type contexts. "Eager resolution" is context simplification. The only reason it's reasonable to use pairs is if we decide to enforce overload freedom, as I described in my blog post.

Also, to ensure termination, it may be necessary to add a depth to these pairs, unless we decide to enforce something like Haskell's Paterson or Basic conditions (which I am not sure how I feel about).

@ghost ghost assigned nikomatsakis Oct 12, 2012
@nikomatsakis
Copy link
Contributor Author

Here is a test case where inference fails:

struct Vec2 {
    x: float,
    y: float
}

// methods we want to export as methods as well as operators
impl Vec2 {
#[inline(always)]
    pure fn vmul(other: float) -> Vec2 {
        Vec2 { x: self.x * other, y: self.y * other }
    }
}

// Right-hand-side operator visitor pattern
trait RhsOfVec2Mul<Result> { pure fn mul_vec2_by(lhs: &Vec2) -> Result; }

// Vec2's implementation of Mul "from the other side" using the above trait
impl<Res, Rhs: RhsOfVec2Mul<Res>> Vec2: Mul<Rhs,Res> {
    pure fn mul(rhs: &Rhs) -> Res { rhs.mul_vec2_by(&self) }
}

// Implementation of 'float as right-hand-side of Vec2::Mul'
impl float: RhsOfVec2Mul<Vec2> {
    pure fn mul_vec2_by(lhs: &Vec2) -> Vec2 { lhs.vmul(self) }
}

// Usage with failing inference
fn main() {
    let a = Vec2 { x: 3f, y: 4f };

    // the following compiles and works properly
    let v1: Vec2 = a * 3f;
    io::println(fmt!("%f %f", v1.x, v1.y));

    // the following compiles but v2 will not be Vec2 yet and
    // using it later will cause an error that the type of v2
    // must be known
    let v2 = a * 3f;
    io::println(fmt!("%f %f", v2.x, v2.y)); // error regarding v2's type
}

@nikomatsakis
Copy link
Contributor Author

Actually, this example is illustrating a bit of a different bug than I thought it was. Here the bug is that operator overloading doesnt' attempt eager resolution. If you rewrite 'a * 3f' to 'a.mul(3f)' it works fine.

@nikomatsakis
Copy link
Contributor Author

I still think we should do this refactoring but I am not sure if it it will ultimately make inference work any better =)

@catamorphism
Copy link
Contributor

Nominating for milestone 5, production-ready

@pnkfelix
Copy link
Member

punting to later bug triage with niko present

@graydon
Copy link
Contributor

graydon commented Jul 11, 2013

accepted for well-defined milestone

@flaper87
Copy link
Contributor

Triage bump. It still needs to be implemented.

@nikomatsakis mentioned he has a concrete plan for it and he'll write it down later this week.

@treeman
Copy link
Contributor

treeman commented Aug 25, 2014

Triage bump. Is this relevant? I tried and failed to create a test case for it.

Might be related to #5527?

@aturon
Copy link
Member

aturon commented Sep 18, 2014

Nominating for removal from "P-backcompat-lang". Should this issue even be open any more?

@pnkfelix
Copy link
Member

closing as dupe of #5527.

bors pushed a commit to rust-lang-ci/rust that referenced this issue May 15, 2021
flip1995 pushed a commit to flip1995/rust that referenced this issue Jun 3, 2021
Move `needless_borrow` to style

fixes: rust-lang#3742

rust-lang#7105 should be merged first to fix the false positive.

changelog: move `needless_borrow` from `nursery` to `style`
RalfJung pushed a commit to RalfJung/rust that referenced this issue Jul 29, 2024
TB: Reserved + Protected + IM + lazy is a horrible combination that should not exist

As discovered by `@JoJoDeveloping,` the result of having both Protector exceptions on lazy locations (protectors only protect initialized bytes) and interior mutability exceptions for protected tags (Reserved IM does not accept foreign writes when protected) leads to some very undesirable results, namely that we cannot do spurious writes even on protected activated locations.

We propose that Protected Reserved IM should no longer exist and instead when a type is retagged as part of a `FnEntry` it is assumed to lose interior mutability.

In fact, this was already being done implicitly because relevant transitions were guarded by an `if protected`, but the difference is that now it also applies to transitions that occur after the end of the protector.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

7 participants