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

Returning Self in impl Trait does not resolve member types (+ Compiler Crash) #57399

Closed
ISibboI opened this issue Jan 7, 2019 · 3 comments · Fixed by #65191
Closed

Returning Self in impl Trait does not resolve member types (+ Compiler Crash) #57399

ISibboI opened this issue Jan 7, 2019 · 3 comments · Fixed by #65191
Labels
C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ISibboI
Copy link

ISibboI commented Jan 7, 2019

A code sample demonstrating the problem:

trait T {
    type T;
}

impl T for i32 {
    type T = u32;
}

struct S<A> {
    a: A,
}

/*// Works
impl From<u32> for S<<i32 as T>::T> {
    fn from(a: u32) -> S<<i32 as T>::T> {
        S::<<i32 as T>::T> {a}
    }
}*/

/*// Works
impl From<u32> for S<<i32 as T>::T> {
    fn from(a: u32) -> Self {
        S::<<i32 as T>::T> {a}
    }
}*/

/*// Fails
impl From<u32> for S<<i32 as T>::T> {
    fn from(a: u32) -> Self {
        Self {a}
    }
}*/

// Fails
impl From<u32> for S<<i32 as T>::T> {
    fn from(a: u32) -> S<<i32 as T>::T> {
        Self {a}
    }
}

fn main() {
}

Playground

The error:

  --> src/main.rs:37:9
   |
36 |     fn from(a: u32) -> S<<i32 as T>::T> {
   |                        ---------------- expected `S<u32>` because of return type
37 |         Self {a}
   |         ^^^^^^^^ expected u32, found associated type
   |
   = note: expected type `S<u32>`
              found type `S<<i32 as T>::T>`

The Observed behaviour occurs on stable 1.31.1.
I would expect this to compile, as Self is just an alias for S<<i32 as T>::T> in this case.

On the current nightly (nightly-x86_64-unknown-linux-gnu unchanged - rustc 1.33.0-nightly (b92552d55 2019-01-06)), using the same construction in a more complicated environment leads to a compiler crash:

   --> src/graph/td_cch/mod.rs:973:26
    |
973 |           let mut result = Self {
    |  __________________________^
974 | |             source_nodes,
975 | |             first_in,
976 | |             first_out,
...   |
982 | |             weights: functions,
983 | |         };
    | |_________^

error: internal compiler error: broken MIR in DefId(0/0:390 ~ proof_of_concept[a4c9]::graph[0]::td_cch[0]::{{impl}}[6]::from[0]) (_0 = move _103): bad assignment (graph::td_cch::TDCCH<plf::Point, plf::PLFunctionBuilder> = graph::td_cch::TDCCH<<plf::PLFunctionBuilder as graph::WeightFunctionBuilder>::Weight, plf::PLFunctionBuilder>): NoSolution
   --> src/graph/td_cch/mod.rs:984:9
    |
984 |         result
    |         ^^^^^^

thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:324:17
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.33.0-nightly (b92552d55 2019-01-06) running on x86_64-unknown-linux-gnu

note: compiler flags: -C debuginfo=2 -C incremental -C target-cpu=native --crate-type bin

note: some of the compiler flags provided by cargo are hidden

error: Could not compile `proof_of_concept`.

I cannot disclose the full code, but here are some samples I think are relevant:
The method around the crash:

impl From<EdgeList<Point, ()>> for PLTDCCH {
    fn from(edge_list: EdgeList<Point, ()>) -> Self {
        let edges = edge_list.edges;
        let functions = edge_list.weights;

        let mut source_nodes = vec![0; edges.len()];
        let mut first_in = vec![0; edge_list.node_count as usize + 2];
        let mut first_out = vec![0; edge_list.node_count as usize + 1];
        let mut target_nodes = Vec::with_capacity(edges.len());
        let mut weight_builders = Vec::with_capacity(edges.len());

        for edge in &edges {
            first_in[edge.end as usize + 1] += 1;
            first_out[edge.start as usize] += 1;
            target_nodes.push(edge.end);
            weight_builders.push(PLFunctionBuilder::new(edge.weight_start, edge.weight_end));
        }

        first_in.prefix_sum();
        first_out.prefix_sum();

        for edge in &edges {
            let index = &mut first_in[edge.end as usize + 1];
            source_nodes[*index as usize] = edge.start;
            let weights = &functions[edge.weight_start as usize..edge.weight_end as usize];
            *index += 1;
        }

        first_in.pop();

        let mut result = Self {
            source_nodes,
            first_in,
            first_out,
            target_nodes,
            out_to_in_edges: Vec::new(),
            in_to_out_edges: Vec::new(),

            weight_builders: weight_builders,
            weights: functions,
        };
        result
    }
}

The PLTDCCH type:

#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TDCCH<W, WFB> {
    source_nodes: Vec<NodeId>,
    first_in: Vec<EdgeId>,
    first_out: Vec<EdgeId>,
    target_nodes: Vec<NodeId>,
    out_to_in_edges: Vec<EdgeId>,
    in_to_out_edges: Vec<EdgeId>,

    weight_builders: Vec<WFB>,
    weights: Vec<W>,
}

pub type PLTDCCH = TDCCH<<PLFunctionBuilder as WeightFunctionBuilder>::Weight, PLFunctionBuilder>;

The WeightFunctionBuilder trait:

pub trait WeightFunctionBuilder: Link<Self> + Merge<Self> + Clone + Serialize + for<'de> Deserialize<'de> {
    type Weight: Clone + Debug;
    // [...]
}
@ISibboI ISibboI changed the title Returning Self in impl Trait does not resolve member types Returning Self in impl Trait does not resolve member types (+ Compiler Crash) Jan 7, 2019
@varkor varkor added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Jan 7, 2019
@jonas-schievink jonas-schievink added C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 6, 2019
@jakubadamw
Copy link
Contributor

The very first snippet has been successfully compiling since 1.35.0.

@rustbot modify labels: E-needstest

@rustbot rustbot added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Sep 29, 2019
@ISibboI
Copy link
Author

ISibboI commented Sep 30, 2019

Amazing. The project this code was for actually is over, but if it helps I can try to find the old commit and check if it compiles without ICE on the current nightly. Would that be required for this issue to move forward?

@jakubadamw
Copy link
Contributor

@ISibboI, thank you for your offer but I don't think that's strictly necessary! 🙂 I added the E-needstest label, which means that for this issue to be closed a regression test will need to be added to the test suite. There are dozens of issues with the tag open¹ and every now and then contributors go over them, often adding test cases en masse.

¹ https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AE-needstest

varkor added a commit to varkor/rust that referenced this issue Oct 7, 2019
tmandry added a commit to tmandry/rust that referenced this issue Oct 11, 2019
…=nikomatsakis

Add some regression tests

- Add a test for rust-lang#62187.
- Clean up the directory structure in `src/test/ui/const-generics`
- Closes rust-lang#64792.
- Closes rust-lang#57399.
- Closes rust-lang#57271.
tmandry added a commit to tmandry/rust that referenced this issue Oct 11, 2019
…=nikomatsakis

Add some regression tests

- Add a test for rust-lang#62187.
- Clean up the directory structure in `src/test/ui/const-generics`
- Closes rust-lang#64792.
- Closes rust-lang#57399.
- Closes rust-lang#57271.
Centril added a commit to Centril/rust that referenced this issue Oct 11, 2019
…=nikomatsakis

Add some regression tests

- Add a test for rust-lang#62187.
- Clean up the directory structure in `src/test/ui/const-generics`
- Closes rust-lang#64792.
- Closes rust-lang#57399.
- Closes rust-lang#57271.
@bors bors closed this as completed in 728adc4 Oct 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants