fn tell(&self) -> uint;
}
+#[cfg(stage1)]
+#[cfg(stage2)]
+impl Reader for @Reader {
+ fn read(&self, bytes: &mut [u8], len: uint) -> uint {
+ self.read(bytes, len)
+ }
+ fn read_byte(&self) -> int {
+ self.read_byte()
+ }
+ fn eof(&self) -> bool {
+ self.eof()
+ }
+ fn seek(&self, position: int, style: SeekStyle) {
+ self.seek(position, style)
+ }
+ fn tell(&self) -> uint {
+ self.tell()
+ }
+}
+
/// Generic utility functions defined on readers.
pub trait ReaderUtil {
fn get_type(&self) -> WriterType;
}
+#[cfg(stage1)]
+#[cfg(stage2)]
+impl Writer for @Writer {
+ fn write(&self, v: &[const u8]) { self.write(v) }
+ fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) }
+ fn tell(&self) -> uint { self.tell() }
+ fn flush(&self) -> int { self.flush() }
+ fn get_type(&self) -> WriterType { self.get_type() }
+}
+
impl<W:Writer,C> Writer for Wrapper<W, C> {
fn write(&self, bs: &[const u8]) { self.base.write(bs); }
fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); }
// FIXME (#2004) it would be great if this could be a const
// FIXME (#2004) why are these different from the way stdin() is
// implemented?
-pub fn stdout() -> Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
-pub fn stderr() -> Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
+pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
+pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
pub fn print(s: &str) { stdout().write_str(s); }
pub fn println(s: &str) { stdout().write_line(s); }
}
}
}
- typeck::vtable_trait(def_id, tys) => {
- do ebml_w.emit_enum_variant(~"vtable_trait", 1u, 3u) {
- do ebml_w.emit_enum_variant_arg(0u) {
- ebml_w.emit_def_id(def_id)
- }
- do ebml_w.emit_enum_variant_arg(1u) {
- ebml_w.emit_tys(ecx, /*bad*/copy tys);
- }
- }
- }
}
}
}
)
}
- 2 => {
- typeck::vtable_trait(
- do self.read_enum_variant_arg(0u) {
- self.read_def_id(xcx)
- },
- do self.read_enum_variant_arg(1u) {
- self.read_tys(xcx)
- }
- )
- }
// hard to avoid - user input
_ => fail!(~"bad enum variant")
}
})
}
}
- typeck::vtable_trait(_, _) => {
- trans_trait_callee(bcx,
- callee_id,
- n_method,
- base,
- ty::vstore_box,
- mentry.explicit_self)
- }
typeck::vtable_param(*) => {
fail!(~"vtable_param left in monomorphized function's " +
"vtable substs");
None,
None)
}
- typeck::vtable_trait(trait_id, substs) => {
- @mono_id_ {
- def: trait_id,
- params: vec::map(substs, |t| mono_precise(*t, None)),
- impl_did_opt: None
- }
- }
+
// can't this be checked at the callee?
_ => fail!(~"vtable_id")
}
module as the type itself).
Inherent candidates are not always derived from impls. If you have a
-trait instance, such as a value of type `ToStr`, then the trait
+trait instance, such as a value of type `@ToStr`, then the trait
methods (`to_str()`, in this case) are inherently associated with it.
Another case is type parameters, in which case the methods of their
bounds are inherent.
}
method_trait(trait_did, _, _) | method_self(trait_did, _)
| method_super(trait_did, _) => {
- self.report_param_candidate(idx, trait_did)
+ self.report_trait_candidate(idx, trait_did)
}
}
}
use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type};
use middle::typeck::infer;
use middle::typeck::{CrateCtxt, vtable_origin, vtable_param, vtable_res};
-use middle::typeck::{vtable_static, vtable_trait};
+use middle::typeck::{vtable_static};
use util::common::indenter;
use util::ppaux::tys_to_str;
use util::ppaux;
location_info: &LocationInfo,
bounds: @~[ty::param_bounds],
substs: &ty::substs,
- allow_unsafe: bool,
is_early: bool) -> vtable_res {
debug!("lookup_vtables(location_info=%?,
# bounds=%?, \
debug!("after subst: %?",
ppaux::ty_to_str(tcx, trait_ty));
- match lookup_vtable(vcx, location_info, *ty, trait_ty,
- allow_unsafe, is_early) {
+ match lookup_vtable(vcx, location_info, *ty, trait_ty, is_early) {
Some(vtable) => result.push(vtable),
None => {
vcx.tcx().sess.span_fatal(
location_info: &LocationInfo,
ty: ty::t,
trait_ty: ty::t,
- allow_unsafe: bool,
is_early: bool)
-> Option<vtable_origin> {
debug!("lookup_vtable(ty=%s, trait_ty=%s)",
}
}
- ty::ty_trait(did, ref substs, _) if trait_id == did => {
- debug!("(checking vtable) @1 relating ty to trait ty with did %?",
- did);
-
- relate_trait_tys(vcx, location_info, trait_ty, ty);
- if !allow_unsafe && !is_early {
- for vec::each(*ty::trait_methods(tcx, did)) |m| {
- if ty::type_has_self(ty::mk_bare_fn(tcx, copy m.fty)) {
- tcx.sess.span_err(
- location_info.span,
- ~"a boxed trait with self types may not be \
- passed as a bounded type");
- } else if (*m.tps).len() > 0u {
- tcx.sess.span_err(
- location_info.span,
- ~"a boxed trait with generic methods may not \
- be passed as a bounded type");
-
- }
- }
- }
- return Some(vtable_trait(did, /*bad*/copy (*substs).tps));
- }
-
_ => {
let mut found = ~[];
trait_vstore);
let subres = lookup_vtables(
vcx, location_info, im_bs, &substs_f,
- false, is_early);
+ is_early);
// Finally, we register that we found a
// matching impl, and record the def ID of
}
let vcx = VtableContext { ccx: fcx.ccx, infcx: fcx.infcx() };
let vtbls = lookup_vtables(&vcx, &location_info_for_expr(ex),
- item_ty.bounds, substs, false,
- is_early);
+ item_ty.bounds, substs, is_early);
if !is_early {
let vtable_map = cx.vtable_map;
vtable_map.insert(ex.id, vtbls);
let substs = fcx.node_ty_substs(callee_id);
let vcx = VtableContext { ccx: fcx.ccx, infcx: fcx.infcx() };
let vtbls = lookup_vtables(&vcx, &location_info_for_expr(ex),
- bounds, &substs, false, is_early);
+ bounds, &substs, is_early);
if !is_early {
insert_vtables(cx, callee_id, vtbls);
}
location_info,
mt.ty,
target_ty,
- true,
is_early);
match vtable_opt {
Some(vtable) => {
use middle::typeck::infer::{resolve_type};
use middle::typeck::infer;
use middle::typeck::method_map_entry;
-use middle::typeck::{vtable_param, vtable_trait, write_substs_to_tcx};
+use middle::typeck::{vtable_param, write_substs_to_tcx};
use middle::typeck::{write_ty_to_tcx};
use util::ppaux;
The first uint is the param number (identifying T in the example),
and the second is the bound number (identifying baz)
*/
- vtable_param(uint, uint),
- /*
- Dynamic vtable, comes from something known to have a trait
- type. def_id refers to the trait item, tys are the substs
- */
- vtable_trait(ast::def_id, ~[ty::t]),
+ vtable_param(uint, uint)
}
pub impl vtable_origin {
vtable_param(x, y) => {
fmt!("vtable_param(%?, %?)", x, y)
}
-
- vtable_trait(def_id, ref tys) => {
- fmt!("vtable_trait(%?:%s, %?)",
- def_id, ty::item_path_str(tcx, def_id),
- tys.map(|t| ppaux::ty_to_str(tcx, *t)))
- }
}
}
}
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that an object type `@Foo` is not considered to implement the
+// trait `Foo`. Issue #5087.
+
+trait Foo {}
+fn take_foo<F:Foo>(f: F) {}
+fn take_object(f: @Foo) { take_foo(f); } //~ ERROR failed to find an implementation of trait
+fn main() {}
return gc; //~ ERROR mismatched types: expected `@get_ctxt/&b` but found `@get_ctxt/&a`
}
-fn make_gc2(gc: get_ctxt/&a) -> get_ctxt/&b {
- return @gc as get_ctxt; //~ ERROR cannot infer an appropriate lifetime
+struct Foo {
+ r: &'self uint
+}
+
+impl get_ctxt/&self for Foo/&self {
+ fn get_ctxt() -> &self/uint { self.r }
+}
+
+fn make_gc2(foo: Foo/&a) -> get_ctxt/&b {
+ return @foo as get_ctxt; //~ ERROR cannot infer an appropriate lifetime
}
fn main() {
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-trait add {
- fn plus(++x: Self) -> Self;
-}
-
-impl add for int {
- fn plus(++x: int) -> int { self + x }
-}
-
-fn do_add<A:add>(x: A, y: A) -> A { x.plus(y) }
-
-fn main() {
- let x = @3 as @add;
- let y = @4 as @add;
- do_add(x, y); //~ ERROR a boxed trait with self types may not be passed as a bounded type
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-trait foo<T> { }
-
-fn bar(x: foo<uint>) -> foo<int> {
- return (@x as foo::<int>);
- //~^ ERROR mismatched types: expected `@foo<int>` but found `@foo<uint>`
- //~^^ ERROR mismatched types: expected `@foo<int>` but found `@foo<uint>`
- // This is unfortunate -- new handling of parens means the error message
- // gets printed twice
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-trait double {
- fn double() -> uint;
-}
-
-impl double for uint {
- fn double() -> uint { self * 2u }
-}
-
-fn is_equal<D:double>(x: @D, exp: uint) {
- assert x.double() == exp;
-}
-
-pub fn main() {
- let x = @(@3u as @double);
- is_equal(x, 6);
-}
use core::to_str::ToStr;
use cci_class_cast::kitty::*;
-fn print_out<T:ToStr>(thing: T, expected: ~str) {
+fn print_out(thing: @ToStr, expected: ~str) {
let actual = thing.to_str();
debug!("%s", actual);
assert(actual == expected);
}
-fn annoy_neighbors<T:noisy>(critter: T) {
+fn annoy_neighbors(critter: @noisy) {
for uint::range(0u, 10u) |i| { critter.speak(); }
}
pure fn to_str(&self) -> ~str { copy self.name }
}
-fn print_out<T:ToStr>(thing: T, expected: ~str) {
+fn print_out(thing: @ToStr, expected: ~str) {
let actual = thing.to_str();
debug!("%s", actual);
assert(actual == expected);
+++ /dev/null
-pub trait Reader {
- // FIXME (#2004): Seekable really should be orthogonal.
-
- /// Read up to len bytes (or EOF) and put them into bytes (which
- /// must be at least len bytes long). Return number of bytes read.
- // FIXME (#2982): This should probably return an error.
- fn read(&self, bytes: &mut [u8], len: uint) -> uint;
-}
-
-pub trait ReaderUtil {
-
- /// Read len bytes into a new vec.
- fn read_bytes(&self, len: uint);
-}
-
-impl<T:Reader> ReaderUtil for T {
-
- fn read_bytes(&self, len: uint) {
- let mut count = self.read(&mut [0], len);
- }
-
-}
-
-struct S {
- x: int,
- y: int
-}
-
-impl Reader for S {
- fn read(&self, bytes: &mut [u8], len: uint) -> uint {
- 0
- }
-}
-
-pub fn main() {
- let x = S { x: 1, y: 2 };
- let x = @x as @Reader;
- x.read_bytes(0);
-}
+++ /dev/null
-pub trait Reader {
- // FIXME (#2004): Seekable really should be orthogonal.
-
- /// Read up to len bytes (or EOF) and put them into bytes (which
- /// must be at least len bytes long). Return number of bytes read.
- // FIXME (#2982): This should probably return an error.
- fn read(&self, bytes: &mut [u8], len: uint) -> uint;
-}
-
-pub trait ReaderUtil {
-
- /// Read len bytes into a new vec.
- fn read_bytes(&self, len: uint);
-}
-
-impl<T:Reader> ReaderUtil for T {
-
- fn read_bytes(&self, len: uint) {
- let mut count = self.read(&mut [0], len);
- }
-
-}
-
-struct S {
- x: int,
- y: int
-}
-
-impl Reader for S {
- fn read(&self, bytes: &mut [u8], len: uint) -> uint {
- 0
- }
-}
-
-pub fn main() {
- let x = S { x: 1, y: 2 };
- let x = @x as @Reader;
- x.read_bytes(0);
-}
+++ /dev/null
-pub trait Reader {
- // FIXME (#2004): Seekable really should be orthogonal.
-
- /// Read up to len bytes (or EOF) and put them into bytes (which
- /// must be at least len bytes long). Return number of bytes read.
- // FIXME (#2982): This should probably return an error.
- fn read(&self, bytes: &mut [u8], len: uint) -> uint;
-}
-
-pub trait ReaderUtil {
-
- /// Read len bytes into a new vec.
- fn read_bytes(len: uint);
-}
-
-impl<T:Reader> ReaderUtil for T {
-
- fn read_bytes(len: uint) {
- let mut count = self.read(&mut [0], len);
- }
-
-}
-
-struct S {
- x: int,
- y: int
-}
-
-impl Reader for S {
- fn read(&self, bytes: &mut [u8], len: uint) -> uint {
- 0
- }
-}
-
-pub fn main() {
- let x = S { x: 1, y: 2 };
- let x = @x as @Reader;
- x.read_bytes(0);
-}
+++ /dev/null
-pub trait Reader {
- // FIXME (#2004): Seekable really should be orthogonal.
-
- /// Read up to len bytes (or EOF) and put them into bytes (which
- /// must be at least len bytes long). Return number of bytes read.
- // FIXME (#2982): This should probably return an error.
- fn read(bytes: &mut [u8], len: uint) -> uint;
-}
-
-pub trait ReaderUtil {
-
- /// Read len bytes into a new vec.
- fn read_bytes(len: uint);
-}
-
-impl<T:Reader> ReaderUtil for T {
-
- fn read_bytes(len: uint) {
- let mut count = self.read(&mut [0], len);
- }
-
-}
-
-struct S {
- x: int,
- y: int
-}
-
-impl Reader for S {
- fn read(bytes: &mut [u8], len: uint) -> uint {
- 0
- }
-}
-
-pub fn main() {
- let x = S { x: 1, y: 2 };
- let x = @x as @Reader;
- x.read_bytes(0);
-}
use core::iter::BaseIter;
trait FlatMapToVec<A> {
- fn flat_map_to_vec<B, IB:BaseIter<B>>(op: fn(&A) -> IB) -> ~[B];
+ fn flat_map_to_vec<B, IB:BaseIter<B>>(&self, op: fn(&A) -> IB) -> ~[B];
}
-impl<A:Copy> FlatMapToVec<A> for BaseIter<A> {
- fn flat_map_to_vec<B, IB:BaseIter<B>>(op: fn(&A) -> IB) -> ~[B] {
- iter::flat_map_to_vec(&self, op)
+impl<A:Copy> FlatMapToVec<A> for ~[A] {
+ fn flat_map_to_vec<B, IB:BaseIter<B>>(&self, op: fn(&A) -> IB) -> ~[B] {
+ iter::flat_map_to_vec(self, op)
}
}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-trait double {
- fn double() -> uint;
-}
-
-impl double for uint {
- fn double() -> uint { self * 2u }
-}
-
-fn is_equal<D:double>(x: @D, exp: uint) {
- assert x.double() == exp;
-}
-
-pub fn main() {
- let x = @(@3u as @double);
- is_equal(x, 6);
-}