Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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
# for free to join this conversation on GitHub. Already have an account? # 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