Closed
Description
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() {
}
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;
// [...]
}