Skip to content

Commit 04f12ef

Browse files
committed
Auto merge of #31442 - pnkfelix:issue-30438-sidestep-dummy-node-during-expand-givens-dfs, r=nikomatsakis
Split dummy-idx node to fix expand_givens DFS (Much more detail in commit comments.) Fix #30438.
2 parents e06f692 + 77c8850 commit 04f12ef

File tree

4 files changed

+107
-3
lines changed

4 files changed

+107
-3
lines changed

src/librustc/middle/infer/region_inference/mod.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -1105,7 +1105,14 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
11051105
for _ in 0..num_vars {
11061106
graph.add_node(());
11071107
}
1108-
let dummy_idx = graph.add_node(());
1108+
1109+
// Issue #30438: two distinct dummy nodes, one for incoming
1110+
// edges (dummy_source) and another for outgoing edges
1111+
// (dummy_sink). In `dummy -> a -> b -> dummy`, using one
1112+
// dummy node leads one to think (erroneously) there exists a
1113+
// path from `b` to `a`. Two dummy nodes sidesteps the issue.
1114+
let dummy_source = graph.add_node(());
1115+
let dummy_sink = graph.add_node(());
11091116

11101117
for (constraint, _) in constraints.iter() {
11111118
match *constraint {
@@ -1115,10 +1122,10 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
11151122
*constraint);
11161123
}
11171124
ConstrainRegSubVar(_, b_id) => {
1118-
graph.add_edge(dummy_idx, NodeIndex(b_id.index as usize), *constraint);
1125+
graph.add_edge(dummy_source, NodeIndex(b_id.index as usize), *constraint);
11191126
}
11201127
ConstrainVarSubReg(a_id, _) => {
1121-
graph.add_edge(NodeIndex(a_id.index as usize), dummy_idx, *constraint);
1128+
graph.add_edge(NodeIndex(a_id.index as usize), dummy_sink, *constraint);
11221129
}
11231130
}
11241131
}
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Original regression test for Issue #30438.
12+
13+
use std::ops::Index;
14+
15+
struct Test<'a> {
16+
s: &'a String
17+
}
18+
19+
impl <'a> Index<usize> for Test<'a> {
20+
type Output = Test<'a>;
21+
fn index(&self, _: usize) -> &Self::Output {
22+
return &Test { s: &self.s};
23+
//~^ ERROR: borrowed value does not live long enough
24+
}
25+
}
26+
27+
fn main() {
28+
let s = "Hello World".to_string();
29+
let test = Test{s: &s};
30+
let r = &test[0];
31+
println!("{}", test.s); // OK since test is valid
32+
println!("{}", r.s); // Segfault since value pointed by r has already been dropped
33+
}
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Modified regression test for Issue #30438 that exposed an
12+
// independent issue (see discussion on ticket).
13+
14+
use std::ops::Index;
15+
16+
struct Test<'a> {
17+
s: &'a String
18+
}
19+
20+
impl <'a> Index<usize> for Test<'a> {
21+
type Output = Test<'a>;
22+
fn index(&self, _: usize) -> &Self::Output {
23+
&Test { s: &self.s}
24+
//~^ ERROR: borrowed value does not live long enough
25+
}
26+
}
27+
28+
fn main() {
29+
let s = "Hello World".to_string();
30+
let test = Test{s: &s};
31+
let r = &test[0];
32+
println!("{}", test.s); // OK since test is valid
33+
println!("{}", r.s); // Segfault since value pointed by r has already been dropped
34+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Simplfied regression test for #30438, inspired by arielb1.
12+
13+
trait Trait { type Out; }
14+
15+
struct Test<'a> { s: &'a str }
16+
17+
fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y <Test<'z> as Trait>::Out where 'z: 'static {
18+
let x = Test { s: "this cannot last" };
19+
&x
20+
//~^ ERROR: `x` does not live long enough
21+
}
22+
23+
impl<'b> Trait for Test<'b> { type Out = Test<'b>; }
24+
25+
fn main() {
26+
let orig = Test { s: "Hello World" };
27+
let r = silly(&orig);
28+
println!("{}", orig.s); // OK since `orig` is valid
29+
println!("{}", r.s); // Segfault (method does not return a sane value)
30+
}

0 commit comments

Comments
 (0)