Repository navigation
Returning Self in impl Trait does not resolve member types (+ Compiler Crash) #57399
Copy link
Copy link
Closed
Closed
Copy link
Labels
C-bugCategory: This is a bug.Category: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call 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) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
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;
// [...]
}
Metadata
Metadata
Assignees
Labels
C-bugCategory: This is a bug.Category: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call 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) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Activity
[-]Returning Self in impl Trait does not resolve member types[/-][+]Returning Self in impl Trait does not resolve member types (+ Compiler Crash)[/+]jakubadamw commentedon Sep 29, 2019
The very first snippet has been successfully compiling since 1.35.0.
@rustbot modify labels: E-needstest
ISibboI commentedon 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 commentedon Oct 1, 2019
@ISibboI, thank you for your offer but I don't think that's strictly necessary! 🙂 I added the
E-needstestlabel, 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
Add a regression test for rust-lang#57399
Rollup merge of rust-lang#65191 - varkor:const-generics-test-cases, r…
Rollup merge of rust-lang#65191 - varkor:const-generics-test-cases, r…
Rollup merge of rust-lang#65191 - varkor:const-generics-test-cases, r…
Rollup merge of rust-lang#65191 - varkor:const-generics-test-cases, r…