use marker::Sized;
use usize;
-fn _assert_is_object_safe(_: &Iterator) {}
+fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
/// An interface for dealing with "external iterators". These types of iterators
/// can be resumed at any time as all state is stored internally as opposed to
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
}
ty::AdjustDerefRef(ref adj) => {
- self.walk_autoderefs(expr, adj.autoderefs);
- if let Some(ref r) = adj.autoref {
- self.walk_autoref(expr, r, adj.autoderefs);
- } else if adj.unsize.is_some() {
- assert!(adj.autoderefs == 0,
- format!("Expected no derefs with \
- unsize AutoRefs, found: {}",
- adj.repr(self.tcx())));
- let cmt_unadjusted =
- return_if_err!(self.mc.cat_expr_unadjusted(expr));
- self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
- }
+ self.walk_autoderefref(expr, adj);
}
}
}
self.walk_autoderefs(expr, adj.autoderefs);
// Weird hacky special case: AutoUnsizeUniq, which converts
- // from a ~T to a ~Trait etc, always comes in a stylized
+ // from a Box<T> to a Box<Trait> etc, always comes in a stylized
// fashion. In particular, we want to consume the ~ pointer
// being dereferenced, not the dereferenced content (as the
// content is, at least for upcasts, unsized).
- match adj.autoref {
- Some(ty::AutoUnsizeUniq(_)) => {
- assert!(adj.autoderefs == 1,
- format!("Expected exactly 1 deref with Uniq AutoRefs, found: {}",
- adj.autoderefs));
+ if let Some(ty) = adj.unsize {
+ if let ty::ty_uniq(_) = ty.sty {
+ assert!(adj.autoderefs == 0,
+ format!("Expected no derefs with unsize AutoRefs, found: {}",
+ adj.repr(self.tcx())));
let cmt_unadjusted =
return_if_err!(self.mc.cat_expr_unadjusted(expr));
self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
return;
}
- _ => { }
}
- let autoref = adj.autoref.as_ref();
+ //let autoref = adj.autoref.as_ref();
let cmt_derefd = return_if_err!(
self.mc.cat_expr_autoderefd(expr, adj.autoderefs));
- self.walk_autoref(expr, &cmt_derefd, autoref);
+ self.walk_autoref(expr, cmt_derefd, adj.autoref);
}
+
/// Walks the autoref `opt_autoref` applied to the autoderef'd
/// `expr`. `cmt_derefd` is the mem-categorized form of `expr`
/// after all relevant autoderefs have occurred. Because AutoRefs
/// autoref.
fn walk_autoref(&mut self,
expr: &ast::Expr,
- cmt_derefd: &mc::cmt<'tcx>,
- opt_autoref: Option<&ty::AutoRef<'tcx>>)
+ cmt_base: mc::cmt<'tcx>,
+ opt_autoref: Option<ty::AutoRef<'tcx>>)
-> mc::cmt<'tcx>
{
debug!("walk_autoref(expr.id={} cmt_derefd={} opt_autoref={:?})",
expr.id,
- cmt_derefd.repr(self.tcx()),
+ cmt_base.repr(self.tcx()),
opt_autoref);
+ let cmt_base_ty = cmt_base.ty;
+
let autoref = match opt_autoref {
- Some(autoref) => autoref,
+ Some(ref autoref) => autoref,
None => {
- // No recursive step here, this is a base case.
- return cmt_derefd.clone();
+ // No AutoRef.
+ return cmt_base;
}
};
- let cmt_base = self.walk_autoref_recursively(expr, cmt_derefd, baseref);
-
debug!("walk_autoref: expr.id={} cmt_base={}",
expr.id,
cmt_base.repr(self.tcx()));
ty::AutoPtr(r, m) => {
self.delegate.borrow(expr.id,
expr.span,
- cmt_derefd,
+ cmt_base,
*r,
ty::BorrowKind::from_mutbl(m),
AutoRef);
}
- ty::AutoUnsafe(m, ref baseref) => {
- let cmt_base = self.walk_autoref_recursively(expr, cmt_derefd, baseref);
-
+ ty::AutoUnsafe(m) => {
debug!("walk_autoref: expr.id={} cmt_base={}",
expr.id,
cmt_base.repr(self.tcx()));
let adj_ty =
ty::adjust_ty_for_autoref(self.tcx(),
- expr.span,
- cmt_derefd.ty,
+ cmt_base_ty,
opt_autoref);
self.mc.cat_rvalue_node(expr.id, expr.span, adj_ty)
}
- fn walk_autoref_recursively(&mut self,
- expr: &ast::Expr,
- cmt_derefd: &mc::cmt<'tcx>,
- autoref: &Option<Box<ty::AutoRef<'tcx>>>)
- -> mc::cmt<'tcx>
- {
- // Shuffle from a ref to an optional box to an optional ref.
- let autoref: Option<&ty::AutoRef<'tcx>> = autoref.as_ref().map(|b| &**b);
- self.walk_autoref(expr, cmt_derefd, autoref)
- }
-
// When this returns true, it means that the expression *is* a
// method-call (i.e. via the operator-overload). This true result
#[derive(Copy, Clone, Debug)]
pub struct AutoDerefRef<'tcx> {
+ // FIXME with more powerful date structures we could have a better design
+ // here. Some constraints:
+ // unsize => autoref
+ // unsize => autodefs == 0
+
+
/// Apply a number of dereferences, producing an lvalue.
pub autoderefs: usize,
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum AutoRef<'tcx> {
- /// Convert from T to &T
+ /// Convert from T to &T.
AutoPtr(&'tcx Region, ast::Mutability),
- /// Convert from T to *T
- /// Value to thin pointer
+ /// Convert from T to *T.
+ /// Value to thin pointer.
AutoUnsafe(ast::Mutability),
}
}
}
- pub fn autoderef(expr_id: ast::NodeId, autoderef: usize) -> MethodCall {
+ pub fn autoderef(expr_id: ast::NodeId, autoderef: u32) -> MethodCall {
MethodCall {
expr_id: expr_id,
autoderef: 1 + autoderef
let method_call = MethodCall::autoderef(expr_id, i as u32);
match method_type(method_call) {
Some(method_ty) => {
- // overloaded deref operators have all late-bound
- // regions fully instantiated and coverge
+ // Overloaded deref operators have all late-bound
+ // regions fully instantiated and coverge.
let fn_ret =
ty::no_late_bound_regions(cx,
&ty_fn_ret(method_ty)).unwrap();
None => {
cx.sess.span_bug(
span,
- &format!("the {}th autoderef failed: \
- {}",
+ &format!("the {}th autoderef failed: {}",
i,
ty_to_string(cx, adjusted_ty))
);
struct Coerce<'a, 'tcx: 'a> {
fcx: &'a FnCtxt<'a, 'tcx>,
origin: infer::TypeOrigin,
- trace: TypeTrace<'tcx>,
unsizing_obligation: Cell<Option<Ty<'tcx>>>
}
if let Some(target) = self.unsize_ty(mt_a.ty, mt_b.ty) {
try!(coerce_mutbls(mt_a.mutbl, mt_b.mutbl));
- let coercion = Coercion(self.trace.clone());
+ let coercion = Coercion(self.origin.span());
let r_borrow = self.fcx.infcx().next_region_var(coercion);
let region = self.tcx().mk_region(r_borrow);
(Some(ty::AutoPtr(region, mt_b.mutbl)), target)
};
let target = ty::adjust_ty_for_autoref(self.tcx(), target, reborrow);
- try!(self.fcx.infcx().try(|_| self.subtype(target, b)));
+ try!(self.subtype(target, b));
let adjustment = AutoDerefRef {
autoderefs: if reborrow.is_some() { 1 } else { 0 },
autoref: reborrow,
assert!(ty_substs_a.len() == ty_substs_b.len());
let tps = ty_substs_a.iter().zip(ty_substs_b.iter()).enumerate();
- for (i, (&tp_a, &tp_b)) in tps {
+ for (i, (tp_a, tp_b)) in tps {
if self.subtype(*tp_a, *tp_b).is_ok() {
continue;
}
-> RelateResult<'tcx, ()> {
debug!("mk_assignty({} -> {})", a.repr(fcx.tcx()), b.repr(fcx.tcx()));
let (adjustment, unsizing_obligation) = try!(indent(|| {
- fcx.infcx().commit_if_ok(|| {
- let origin = infer::ExprAssignable(expr.span);
+ fcx.infcx().commit_if_ok(|_| {
let coerce = Coerce {
fcx: fcx,
origin: infer::ExprAssignable(expr.span),
- trace: infer::TypeTrace::types(origin, false, a, b),
unsizing_obligation: Cell::new(None)
};
Ok((try!(coerce.coerce(expr, a, b)),
let method = match trait_did {
Some(trait_did) => {
- let noop = ty::AutoDerefRef { autoderefs: 0, autoref: None };
- method::lookup_in_trait_adjusted(fcx, expr.span, Some(lhs_expr), opname,
- trait_did, noop, lhs_ty, Some(other_tys))
+ method::lookup_in_trait_adjusted(fcx,
+ expr.span,
+ Some(lhs_expr),
+ opname,
+ trait_did,
+ 0,
+ false,
+ lhs_ty,
+ Some(other_tys))
}
None => None
};
ty::AutoUnsafe(m) => {
let r = ty::ReScope(CodeExtent::from_node_id(expr.id));
- link_region(rcx, expr.span, r, ty::BorrowKind::from_mutbl(m), expr_cmt);
+ link_region(rcx, expr.span, &r, ty::BorrowKind::from_mutbl(m), expr_cmt);
}
}
}
use middle::traits::{Obligation, ObligationCause};
use middle::traits::report_fulfillment_errors;
use middle::ty::{self, Ty, AsPredicate};
-use syntax::ast;
use syntax::codemap::Span;
use util::ppaux::{Repr, UserString};
fn dent_object<COLOR>(c: BoxCar<Color=COLOR>) {
//~^ ERROR ambiguous associated type
- //~| ERROR the associated type `Color` (from the trait `Box`) must be specified
- //~| ERROR the associated type `Color` (from the trait `Vehicle`) must be specified
+ //~| ERROR the value of the associated type `Color` (from the trait `Vehicle`) must be specified
+ //~| NOTE could derive from `Vehicle`
+ //~| NOTE could derive from `Box`
}
fn paint<C:BoxCar>(c: C, d: C::Color) {
type Test = Add +
//~^ ERROR the type parameter `RHS` must be explicitly specified in an object type because its default value `Self` references the type `Self`
+ //~^^ ERROR the value of the associated type `Output` (from the trait `core::ops::Add`) must be specified [E0191]
Sub;
//~^ ERROR only the builtin traits can be used as closure or object bounds
#![ crate_name = "test" ]
#![allow(unstable)]
-#![feature(box_syntax, old_io, rustc_private, core)]
+#![feature(box_syntax, old_io, rustc_private, core, zero_one)]
extern crate graphviz;
// A simple rust project
use sub::sub2 as msalias;
use sub::sub2;
use sub::sub2::nested_struct as sub_struct;
-use std::num::Float;
+use std::num::One;
use std::num::cast;
use std::num::{from_int,from_i8,from_i32};
let s = sub_struct{ field2: 45, };
// import tests
- fn foo(x: &Float) {}
+ fn foo(x: &One) {}
let _: Option<u8> = from_i32(45);
let x = 42;