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.
This commit is contained in:
parent
98e237a681
commit
df714cfda7
@ -142,8 +142,8 @@ impl<'a, 'tcx> dot::Labeller<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 't
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 'tcx> {
|
||||
fn nodes(&self) -> dot::Nodes<'a, Node<'a>> { self.inner.nodes() }
|
||||
fn edges(&self) -> dot::Edges<'a, Edge<'a>> { self.inner.edges() }
|
||||
fn source(&self, edge: &Edge<'a>) -> Node<'a> { self.inner.source(edge) }
|
||||
fn target(&self, edge: &Edge<'a>) -> Node<'a> { self.inner.target(edge) }
|
||||
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.inner.nodes() }
|
||||
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.inner.edges() }
|
||||
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.inner.source(edge) }
|
||||
fn target(&'a self, edge: &Edge<'a>) -> Node<'a> { self.inner.target(edge) }
|
||||
}
|
||||
|
@ -91,19 +91,19 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
|
||||
}
|
||||
|
||||
impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG {
|
||||
fn nodes(&self) -> dot::Nodes<'a, Node<'a>> {
|
||||
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> {
|
||||
let mut v = Vec::new();
|
||||
self.graph.each_node(|i, nd| { v.push((i, nd)); true });
|
||||
dot::maybe_owned_vec::Growable(v)
|
||||
}
|
||||
fn edges(&self) -> dot::Edges<'a, Edge<'a>> {
|
||||
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> {
|
||||
self.graph.all_edges().iter().collect()
|
||||
}
|
||||
fn source(&self, edge: &Edge<'a>) -> Node<'a> {
|
||||
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> {
|
||||
let i = edge.source();
|
||||
(i, self.graph.node(i))
|
||||
}
|
||||
fn target(&self, edge: &Edge<'a>) -> Node<'a> {
|
||||
fn target(&'a self, edge: &Edge<'a>) -> Node<'a> {
|
||||
let i = edge.target();
|
||||
(i, self.graph.node(i))
|
||||
}
|
||||
@ -111,9 +111,9 @@ impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG {
|
||||
|
||||
impl<'a, 'ast> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast>
|
||||
{
|
||||
fn nodes(&self) -> dot::Nodes<'a, Node<'a>> { self.cfg.nodes() }
|
||||
fn edges(&self) -> dot::Edges<'a, Edge<'a>> { self.cfg.edges() }
|
||||
fn source(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) }
|
||||
fn target(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.target(edge) }
|
||||
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.cfg.nodes() }
|
||||
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.cfg.edges() }
|
||||
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) }
|
||||
fn target(&'a self, edge: &Edge<'a>) -> Node<'a> { self.cfg.target(edge) }
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// Check that method bounds declared on traits/impls in a cross-crate
|
||||
// scenario work. This is the libary portion of the test.
|
||||
// scenario work. This is the library portion of the test.
|
||||
|
||||
pub enum MaybeOwned<'a> {
|
||||
Owned(int),
|
||||
@ -24,10 +24,19 @@ pub struct Inv<'a> { // invariant w/r/t 'a
|
||||
// trait, so I'll use that as the template for this test.
|
||||
pub trait IntoMaybeOwned<'a> {
|
||||
fn into_maybe_owned(self) -> MaybeOwned<'a>;
|
||||
|
||||
// Note: without this `into_inv` method, the trait is
|
||||
// contravariant w/r/t `'a`, since if you look strictly at the
|
||||
// interface, it only returns `'a`. This complicates the
|
||||
// downstream test since it wants invariance to force an error.
|
||||
// Hence we add this method.
|
||||
fn into_inv(self) -> Inv<'a>;
|
||||
|
||||
fn bigger_region<'b:'a>(self, b: Inv<'b>);
|
||||
}
|
||||
|
||||
impl<'a> IntoMaybeOwned<'a> for Inv<'a> {
|
||||
fn into_maybe_owned(self) -> MaybeOwned<'a> { fail!() }
|
||||
fn into_inv(self) -> Inv<'a> { fail!() }
|
||||
fn bigger_region<'b:'a>(self, b: Inv<'b>) { fail!() }
|
||||
}
|
||||
|
@ -18,15 +18,15 @@ use lib::Inv;
|
||||
use lib::MaybeOwned;
|
||||
use lib::IntoMaybeOwned;
|
||||
|
||||
fn call_into_maybe_owned<'a,F:IntoMaybeOwned<'a>>(f: F) {
|
||||
fn call_into_maybe_owned<'x,F:IntoMaybeOwned<'x>>(f: F) {
|
||||
// Exercise a code path I found to be buggy. We were not encoding
|
||||
// the region parameters from the receiver correctly on trait
|
||||
// methods.
|
||||
f.into_maybe_owned();
|
||||
}
|
||||
|
||||
fn call_bigger_region<'a, 'b>(a: Inv<'a>, b: Inv<'b>) {
|
||||
// Here the value provided for 'y is 'b, and hence 'b:'a does not hold.
|
||||
fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) {
|
||||
// Here the value provided for 'y is 'y, and hence 'y:'x does not hold.
|
||||
a.bigger_region(b) //~ ERROR cannot infer
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,13 @@ impl Mul<f64, i32> for Vec3 {
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
Vec1 { x: 1.0 } * 2.0;
|
||||
Vec2 { x: 1.0, y: 2.0 } * 2.0;
|
||||
Vec3 { x: 1.0, y: 2.0, z: 3.0 } * 2.0;
|
||||
// Check that the usage goes from the trait declaration:
|
||||
|
||||
let x: Vec1 = Vec1 { x: 1.0 } * 2.0; // this is OK
|
||||
|
||||
let x: Vec2 = Vec2 { x: 1.0, y: 2.0 } * 2.0; // trait had reversed order
|
||||
//~^ ERROR mismatched types
|
||||
//~^^ ERROR mismatched types
|
||||
|
||||
let x: i32 = Vec3 { x: 1.0, y: 2.0, z: 3.0 } * 2.0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user