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

Need check for multiple applicable items in scope #355

Closed
philberty opened this issue Apr 5, 2021 · 0 comments · Fixed by #358
Closed

Need check for multiple applicable items in scope #355

philberty opened this issue Apr 5, 2021 · 0 comments · Fixed by #358
Assignees
Labels
bug diagnostic diagnostic static analysis

Comments

@philberty
Copy link
Member

struct Foo<A> {
    a: A,
}

impl Foo<isize> {
    fn test() -> i32 {
        123
    }

    fn bar(self) -> isize {
        self.a
    }
}

impl Foo<char> {
    fn test() -> i32 {
        123
    }
    
    fn bar(self) -> char {
        self.a
    }
}

fn main() {
    let a:i32 = Foo::test();
}

This error only occurs when the compiler needs to resolve the PathExpr because it can resolve to multiple items.

error[E0034]: multiple applicable items in scope
  --> src/main.rs:29:22
   |
29 |     let a:i32 = Foo::test();
   |                      ^^^^ multiple `test` found
   |
note: candidate #1 is defined in an impl for the type `Foo<isize>`
  --> src/main.rs:8:5
   |
8  |     fn test() -> i32 {
   |     ^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl for the type `Foo<char>`
@philberty philberty added bug diagnostic diagnostic static analysis labels Apr 5, 2021
@philberty philberty added this to the Data Structures 2 - Generics milestone Apr 5, 2021
@philberty philberty self-assigned this Apr 5, 2021
@philberty philberty added this to To do in Data Structures 2 - Generics via automation Apr 5, 2021
philberty added a commit that referenced this issue Apr 10, 2021
In order to support name resolution and checks for duplicate definitions
of names we need canonical paths for all DefId items such as inherent impl
items and normal items.

Consider:

  struct Foo<T>(T);

  impl Foo<f32> {
    fn name()...
  }

  impl Foo<i32> {
    fn name()...
  }

Each of the impl blocks have a name function but these are seperate due to
the concrete impl of the Parameter type passed in.

The caveat here is that to call this Function name the programmer must be
explicit in which implentation they wish to call such as:

  let a = Foo::<f32>::name();

This lets the Path probe lookup the apropriate impl block. The problem here
is that rust also allows for the compiler to infer the impl you wish such
as:

  let a = Foo::name();

This should fail since there are multiple candidates possible for this
Path. Unless there might have only been one name function in which case
it would have worked.

This does not support looking for any inherent impl items overlapping such
as: rustc_typeck/src/coherence/inherent_impls_overlap.rs - see #353

Fixes #355 #335
@philberty philberty moved this from To do to Review in progress in Data Structures 2 - Generics Apr 12, 2021
philberty added a commit that referenced this issue Apr 12, 2021
In order to support name resolution and checks for duplicate definitions
of names we need canonical paths for all DefId items such as inherent impl
items and normal items.

Consider:

  struct Foo<T>(T);

  impl Foo<f32> {
    fn name()...
  }

  impl Foo<i32> {
    fn name()...
  }

Each of the impl blocks have a name function but these are seperate due to
the concrete impl of the Parameter type passed in.

The caveat here is that to call this Function name the programmer must be
explicit in which implentation they wish to call such as:

  let a = Foo::<f32>::name();

This lets the Path probe lookup the apropriate impl block. The problem here
is that rust also allows for the compiler to infer the impl you wish such
as:

  let a = Foo::name();

This should fail since there are multiple candidates possible for this
Path. Unless there might have only been one name function in which case
it would have worked.

This does not support looking for any inherent impl items overlapping such
as: rustc_typeck/src/coherence/inherent_impls_overlap.rs - see #353

Fixes #355 #335 #325
bors bot added a commit that referenced this issue Apr 12, 2021
358: Canonical Paths for Name Resolution and handle TurboFish properly r=philberty a=philberty

Add Canonical paths to name resolution
    
In order to support name resolution and checks for duplicate definitions
of names we need canonical paths for all DefId items such as inherent impl
items and normal items. Consider:

```rust
  struct Foo<T>(T);

  impl Foo<f32> {
    fn name()...
  }

  impl Foo<i32> {
    fn name()...
  }
```

Each of the impl blocks have a name function but these are separate due to
the concrete impl of the Parameter type passed in.

The caveat here is that to call this Function name the programmer must be
explicit in which implentation they wish to call such as:

```rust
  let a = Foo::<f32>::name();
```

This lets the Path probe lookup the appropriate impl block. The problem here
is that rust also allows for the compiler to infer the impl you wish such
as:

```rust
  let a = Foo::name();
```

This should fail since there are multiple candidates possible for this
Path. Unless there might have only been one name function in which case
it would have worked.

This patch is also responsible to implement PathInExpression by iterating
each segment and applying generic arguments as we go.

Fixes #355 #335 #325 #353


Co-authored-by: Philip Herron <philip.herron@embecosm.com>
bors bot added a commit that referenced this issue Apr 13, 2021
358: Canonical Paths for Name Resolution and handle TurboFish properly r=philberty a=philberty

Add Canonical paths to name resolution
    
In order to support name resolution and checks for duplicate definitions
of names we need canonical paths for all DefId items such as inherent impl
items and normal items. Consider:

```rust
  struct Foo<T>(T);

  impl Foo<f32> {
    fn name()...
  }

  impl Foo<i32> {
    fn name()...
  }
```

Each of the impl blocks have a name function but these are separate due to
the concrete impl of the Parameter type passed in.

The caveat here is that to call this Function name the programmer must be
explicit in which implentation they wish to call such as:

```rust
  let a = Foo::<f32>::name();
```

This lets the Path probe lookup the appropriate impl block. The problem here
is that rust also allows for the compiler to infer the impl you wish such
as:

```rust
  let a = Foo::name();
```

This should fail since there are multiple candidates possible for this
Path. Unless there might have only been one name function in which case
it would have worked.

This patch is also responsible to implement PathInExpression by iterating
each segment and applying generic arguments as we go.

Fixes #355 #335 #325 #353


Co-authored-by: Philip Herron <philip.herron@embecosm.com>
@bors bors bot closed this as completed in #358 Apr 13, 2021
@bors bors bot closed this as completed in 85f5874 Apr 13, 2021
Data Structures 2 - Generics automation moved this from Review in progress to Done Apr 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug diagnostic diagnostic static analysis
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

1 participant