diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 9f378748d200..c756d3cb9c28 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -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) {} /// 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 diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index c1c551c2be9e..4f9ac3dd8ef2 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -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 to a Box 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>) -> 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>>) - -> 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 diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index ccb0fa7bfdb4..e0b32ed06a40 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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)) ); diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index acdeda3d546b..28df1c215957 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -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>> } @@ -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)), diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 7c1fea4e60f6..b4000788d199 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -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 }; diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index a7c2969fb7f7..6dfc1e0ea6c2 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -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); } } } diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index f301c89333e3..a9094fce57c6 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -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}; diff --git a/src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs b/src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs index c18d72c445b3..2b34fcab24c0 100644 --- a/src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs +++ b/src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs @@ -34,8 +34,9 @@ fn dent(c: C, color: C::Color) { fn dent_object(c: BoxCar) { //~^ 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: C, d: C::Color) { diff --git a/src/test/compile-fail/issue-22560.rs b/src/test/compile-fail/issue-22560.rs index b458e10a89c2..a05bbe4960e7 100644 --- a/src/test/compile-fail/issue-22560.rs +++ b/src/test/compile-fail/issue-22560.rs @@ -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 diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs index 9d1ab00359dd..56da6693939e 100644 --- a/src/test/run-make/save-analysis/foo.rs +++ b/src/test/run-make/save-analysis/foo.rs @@ -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: Option<::Item>) { let s = sub_struct{ field2: 45, }; // import tests - fn foo(x: &Float) {} + fn foo(x: &One) {} let _: Option = from_i32(45); let x = 42;