Skip to content

Commit df714cf

Browse files
committed
The new method lookup mechanism typechecks calls against the method type declared in the trait, not in the impl. In some cases that results in tighter rules, and in some cases looser. Correct for that.
1 parent 98e237a commit df714cf

File tree

5 files changed

+34
-19
lines changed

5 files changed

+34
-19
lines changed

src/librustc/middle/borrowck/graphviz.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ impl<'a, 'tcx> dot::Labeller<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 't
142142
}
143143

144144
impl<'a, 'tcx> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 'tcx> {
145-
fn nodes(&self) -> dot::Nodes<'a, Node<'a>> { self.inner.nodes() }
146-
fn edges(&self) -> dot::Edges<'a, Edge<'a>> { self.inner.edges() }
147-
fn source(&self, edge: &Edge<'a>) -> Node<'a> { self.inner.source(edge) }
148-
fn target(&self, edge: &Edge<'a>) -> Node<'a> { self.inner.target(edge) }
145+
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.inner.nodes() }
146+
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.inner.edges() }
147+
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.inner.source(edge) }
148+
fn target(&'a self, edge: &Edge<'a>) -> Node<'a> { self.inner.target(edge) }
149149
}

src/librustc/middle/cfg/graphviz.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -91,29 +91,29 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
9191
}
9292

9393
impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG {
94-
fn nodes(&self) -> dot::Nodes<'a, Node<'a>> {
94+
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> {
9595
let mut v = Vec::new();
9696
self.graph.each_node(|i, nd| { v.push((i, nd)); true });
9797
dot::maybe_owned_vec::Growable(v)
9898
}
99-
fn edges(&self) -> dot::Edges<'a, Edge<'a>> {
99+
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> {
100100
self.graph.all_edges().iter().collect()
101101
}
102-
fn source(&self, edge: &Edge<'a>) -> Node<'a> {
102+
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> {
103103
let i = edge.source();
104104
(i, self.graph.node(i))
105105
}
106-
fn target(&self, edge: &Edge<'a>) -> Node<'a> {
106+
fn target(&'a self, edge: &Edge<'a>) -> Node<'a> {
107107
let i = edge.target();
108108
(i, self.graph.node(i))
109109
}
110110
}
111111

112112
impl<'a, 'ast> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast>
113113
{
114-
fn nodes(&self) -> dot::Nodes<'a, Node<'a>> { self.cfg.nodes() }
115-
fn edges(&self) -> dot::Edges<'a, Edge<'a>> { self.cfg.edges() }
116-
fn source(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) }
117-
fn target(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.target(edge) }
114+
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.cfg.nodes() }
115+
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.cfg.edges() }
116+
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) }
117+
fn target(&'a self, edge: &Edge<'a>) -> Node<'a> { self.cfg.target(edge) }
118118
}
119119

src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
// Check that method bounds declared on traits/impls in a cross-crate
12-
// scenario work. This is the libary portion of the test.
12+
// scenario work. This is the library portion of the test.
1313

1414
pub enum MaybeOwned<'a> {
1515
Owned(int),
@@ -24,10 +24,19 @@ pub struct Inv<'a> { // invariant w/r/t 'a
2424
// trait, so I'll use that as the template for this test.
2525
pub trait IntoMaybeOwned<'a> {
2626
fn into_maybe_owned(self) -> MaybeOwned<'a>;
27+
28+
// Note: without this `into_inv` method, the trait is
29+
// contravariant w/r/t `'a`, since if you look strictly at the
30+
// interface, it only returns `'a`. This complicates the
31+
// downstream test since it wants invariance to force an error.
32+
// Hence we add this method.
33+
fn into_inv(self) -> Inv<'a>;
34+
2735
fn bigger_region<'b:'a>(self, b: Inv<'b>);
2836
}
2937

3038
impl<'a> IntoMaybeOwned<'a> for Inv<'a> {
3139
fn into_maybe_owned(self) -> MaybeOwned<'a> { fail!() }
40+
fn into_inv(self) -> Inv<'a> { fail!() }
3241
fn bigger_region<'b:'a>(self, b: Inv<'b>) { fail!() }
3342
}

src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ use lib::Inv;
1818
use lib::MaybeOwned;
1919
use lib::IntoMaybeOwned;
2020

21-
fn call_into_maybe_owned<'a,F:IntoMaybeOwned<'a>>(f: F) {
21+
fn call_into_maybe_owned<'x,F:IntoMaybeOwned<'x>>(f: F) {
2222
// Exercise a code path I found to be buggy. We were not encoding
2323
// the region parameters from the receiver correctly on trait
2424
// methods.
2525
f.into_maybe_owned();
2626
}
2727

28-
fn call_bigger_region<'a, 'b>(a: Inv<'a>, b: Inv<'b>) {
29-
// Here the value provided for 'y is 'b, and hence 'b:'a does not hold.
28+
fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) {
29+
// Here the value provided for 'y is 'y, and hence 'y:'x does not hold.
3030
a.bigger_region(b) //~ ERROR cannot infer
3131
}
3232

src/test/compile-fail/wrong-mul-method-signature.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@ impl Mul<f64, i32> for Vec3 {
5858
}
5959

6060
pub fn main() {
61-
Vec1 { x: 1.0 } * 2.0;
62-
Vec2 { x: 1.0, y: 2.0 } * 2.0;
63-
Vec3 { x: 1.0, y: 2.0, z: 3.0 } * 2.0;
61+
// Check that the usage goes from the trait declaration:
62+
63+
let x: Vec1 = Vec1 { x: 1.0 } * 2.0; // this is OK
64+
65+
let x: Vec2 = Vec2 { x: 1.0, y: 2.0 } * 2.0; // trait had reversed order
66+
//~^ ERROR mismatched types
67+
//~^^ ERROR mismatched types
68+
69+
let x: i32 = Vec3 { x: 1.0, y: 2.0, z: 3.0 } * 2.0;
6470
}

0 commit comments

Comments
 (0)