Skip to content

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

Closed
@ISibboI

Description

@ISibboI

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;
    // [...]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions