Skip to content

Regression in type parameter defaults in types and impls #30123

@bluss

Description

@bluss
Member

This regression is only visible in cross-crate code; NOTE it's very likely it's due to an actual rustc bug fix.

Here is some playpen code for illustration anyway.

Given a struct with default parameters and two constructor functions:

pub struct Graph<N, E, Ty = Directed, Ix: IndexType = DefIndex> {
    nodes: Vec<Node<N, Ix>>,
    edges: Vec<Edge<E, Ix>>,
    ty: PhantomData<Ty>,
}


impl<N, E> Graph<N, E, Directed> {
    pub fn new() -> Self {
        Graph{nodes: Vec::new(), edges: Vec::new(), ty: PhantomData}
    }
}

impl<N, E> Graph<N, E, Undirected> {
    pub fn new_undirected() -> Self {
        Graph{nodes: Vec::new(), edges: Vec::new(), ty: PhantomData}
    }
}

In Rust 1.4 or later (current stable and current nightly), both must be called like this to compile:

    let g = Graph::<i32, i32>::new();
    let ug = Graph::<i32, i32, _>::new_undirected();

In current stable Rust 1.4, the following compiles if you import Graph across crates!

let ug = Graph::<i32, i32>::new_undirected();

This is invalid in current nightly Rust ~1.6, see travis build example; the testcases are in their own crates.

tests/ograph.rs:1018:18: 1018:48 error: no associated item named `new_undirected` found for type `petgraph::graph::Graph<_, ()>` in the current scope
tests/ograph.rs:1018     let mut gr = Graph::<_, ()>::new_undirected();
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Activity

added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
and removed on Dec 9, 2015
nikomatsakis

nikomatsakis commented on Dec 17, 2015

@nikomatsakis
Contributor

This does seem more like a bug fix, but I'm not sure what would have triggered it.

nikomatsakis

nikomatsakis commented on Dec 17, 2015

@nikomatsakis
Contributor

triage: P-high

It's important to decide if this is now doing the correct thing.

self-assigned this
on Dec 17, 2015
bluss

bluss commented on Dec 17, 2015

@bluss
MemberAuthor

I'm sure it's an acceptable fix, but I think we want issues for all regressions, no matter why they happen.

I was mostly amused that there was no way to write a type hinted call of Graph::new_undirected() that would simultaneously compile with Rust 1.4 (requires 2 type params) and Rust 1.6 (requires three); you have to hint the types through the returned value instead.

arielb1

arielb1 commented on Dec 21, 2015

@arielb1
Contributor

The 2-type-param version was working only by a bug - we have no plans of working around that.

nikomatsakis

nikomatsakis commented on Jan 6, 2016

@nikomatsakis
Contributor

@arielb1 do you think you know what fixed it? maybe something in metadata got corrected?

added
relnotesMarks issues that should be documented in the release notes of the next release.
on Jan 6, 2016
brson

brson commented on Jan 8, 2016

@brson
Contributor

I'm trying to bisect to find out what changed, then write a test case.

8 remaining items

arielb1

arielb1 commented on Jan 14, 2016

@arielb1
Contributor

This commit should not have changed anything, but I imagine there is a bug here.

brson

brson commented on Jan 16, 2016

@brson
Contributor

@nikomatsakis nah that's ok. It's not a huge deal. I did start another bisect though. I'm having a hard time summarizing this change for the release notes. There are a lot of technical pieces here. Can somebody try?

bluss

bluss commented on Jan 16, 2016

@bluss
MemberAuthor

@arielb1 My guess could have landed totally wrong. Don't know why I tried. You all know this better than me. For example, as the ImageBuffer example shows, type parameter defaults don't have to be involved, which has me a bit confounded.

brson

brson commented on Jan 18, 2016

@brson
Contributor

I am still trying to bisect.

brson

brson commented on Jan 19, 2016

@brson
Contributor

f5fbefa caused it.

brson

brson commented on Jan 19, 2016

@brson
Contributor
added a commit that references this issue on Jan 19, 2016
arielb1

arielb1 commented on Jan 19, 2016

@arielb1
Contributor

I think the culprit is that I added the

child_name_bindings.define_type(def, DUMMY_SP, modifiers);
arielb1

arielb1 commented on Jan 19, 2016

@arielb1
Contributor

That indeed seems to be the change (commenting it out makes things compile again).

Could someone who understands resolve tell me how the change could cause that kind of effects?

nikomatsakis

nikomatsakis commented on Jan 21, 2016

@nikomatsakis
Contributor

I'm going to close this issue then as "not a bug", since we know that commit caused it.

eddyb

eddyb commented on Feb 21, 2016

@eddyb
Member

@arielb1 Coming back to this, I remember that you removed some metadata code for saving inherent methods: wouldn't they be picked up by resolve, instead of letting typeck do UFCS resolution?

hatahet

hatahet commented on Feb 27, 2016

@hatahet
Contributor

@brson:

My bisection attempt failed.

What caused it to fail the first time?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-betaPerformance or correctness regression from stable to beta.relnotesMarks issues that should be documented in the release notes of the next release.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @eddyb@brson@nikomatsakis@hatahet@arielb1

      Issue actions

        Regression in type parameter defaults in types and impls · Issue #30123 · rust-lang/rust