Rebased
This commit is contained in:
parent
4e8e64140f
commit
73c2e768d6
@ -70,7 +70,7 @@ use option::Option::{self, Some, None};
|
||||
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
|
||||
|
@ -799,18 +799,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -860,29 +849,29 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||
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
|
||||
@ -893,25 +882,25 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||
/// 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()));
|
||||
@ -920,15 +909,13 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||
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()));
|
||||
@ -953,24 +940,12 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||
|
||||
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
|
||||
|
@ -290,6 +290,12 @@ pub enum AutoAdjustment<'tcx> {
|
||||
|
||||
#[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,
|
||||
|
||||
@ -303,11 +309,11 @@ pub struct AutoDerefRef<'tcx> {
|
||||
|
||||
#[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),
|
||||
}
|
||||
|
||||
@ -407,7 +413,7 @@ impl MethodCall {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -4487,8 +4493,8 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
|
||||
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();
|
||||
@ -4501,8 +4507,7 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
|
||||
None => {
|
||||
cx.sess.span_bug(
|
||||
span,
|
||||
&format!("the {}th autoderef failed: \
|
||||
{}",
|
||||
&format!("the {}th autoderef failed: {}",
|
||||
i,
|
||||
ty_to_string(cx, adjusted_ty))
|
||||
);
|
||||
|
@ -79,7 +79,6 @@ use syntax::ast;
|
||||
struct Coerce<'a, 'tcx: 'a> {
|
||||
fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
origin: infer::TypeOrigin,
|
||||
trace: TypeTrace<'tcx>,
|
||||
unsizing_obligation: Cell<Option<Ty<'tcx>>>
|
||||
}
|
||||
|
||||
@ -266,7 +265,7 @@ impl<'f, 'tcx> Coerce<'f, '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)
|
||||
@ -293,7 +292,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
};
|
||||
|
||||
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,
|
||||
@ -374,7 +373,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
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;
|
||||
}
|
||||
@ -498,12 +497,10 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
-> 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)),
|
||||
|
@ -313,9 +313,15 @@ fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
|
||||
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
|
||||
};
|
||||
|
@ -1134,7 +1134,7 @@ fn link_autoref(rcx: &Rcx,
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ use middle::traits::{self, ObjectSafetyViolation, MethodViolationCode};
|
||||
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};
|
||||
|
||||
|
@ -34,8 +34,9 @@ fn dent<C:BoxCar>(c: C, color: C::Color) {
|
||||
|
||||
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) {
|
||||
|
@ -14,6 +14,7 @@ use std::ops::{Add, Sub};
|
||||
|
||||
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
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#![ 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
|
||||
@ -25,7 +25,7 @@ use std::old_io::stdio::println;
|
||||
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};
|
||||
|
||||
@ -42,7 +42,7 @@ fn test_alias<I: Iterator>(i: Option<<I as Iterator>::Item>) {
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user