Skip to content

Commit

Permalink
Rebasing
Browse files Browse the repository at this point in the history
  • Loading branch information
nrc committed May 13, 2015
1 parent db1b14a commit 5d4cce6
Show file tree
Hide file tree
Showing 19 changed files with 118 additions and 109 deletions.
4 changes: 0 additions & 4 deletions src/liballoc/rc.rs
Expand Up @@ -460,7 +460,6 @@ impl<T: ?Sized> Deref for Rc<T> {
}

#[cfg(stage0)] // SNAP c64d671
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for Rc<T> {
/// Drops the `Rc<T>`.
Expand Down Expand Up @@ -512,7 +511,6 @@ impl<T> Drop for Rc<T> {
}

#[cfg(not(stage0))] // SNAP c64d671
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Drop for Rc<T> {
/// Drops the `Rc<T>`.
Expand Down Expand Up @@ -933,7 +931,6 @@ impl<T: ?Sized> Weak<T> {
}

#[cfg(stage0)] // SNAP c64d671
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for Weak<T> {
/// Drops the `Weak<T>`.
Expand Down Expand Up @@ -979,7 +976,6 @@ impl<T> Drop for Weak<T> {
}

#[cfg(not(stage0))] // SNAP c64d671
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Drop for Weak<T> {
/// Drops the `Weak<T>`.
Expand Down
1 change: 0 additions & 1 deletion src/libcore/cell.rs
Expand Up @@ -707,5 +707,4 @@ impl<T: ?Sized> UnsafeCell<T> {
#![allow(trivial_casts)]
&self.value as *const T as *mut T
}

}
9 changes: 9 additions & 0 deletions src/libcore/ops.rs
Expand Up @@ -1220,24 +1220,33 @@ pub trait CoerceUnsized<T> {
// Empty.
}

// &mut T -> &mut U
#[cfg(not(stage0))] // SNAP c64d671
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
// &mut T -> &U
#[cfg(not(stage0))] // SNAP c64d671
impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
// &mut T -> *mut U
#[cfg(not(stage0))] // SNAP c64d671
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
// &mut T -> *const U
#[cfg(not(stage0))] // SNAP c64d671
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}

// &T -> &U
#[cfg(not(stage0))] // SNAP c64d671
impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
// &T -> *const U
#[cfg(not(stage0))] // SNAP c64d671
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}

// *mut T -> *mut U
#[cfg(not(stage0))] // SNAP c64d671
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
// *mut T -> *const U
#[cfg(not(stage0))] // SNAP c64d671
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}

// *const T -> *const U
#[cfg(not(stage0))] // SNAP c64d671
impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
23 changes: 12 additions & 11 deletions src/libcoretest/cell.rs
Expand Up @@ -172,14 +172,15 @@ fn unsafe_cell_unsized() {
assert_eq!(unsafe { &mut *cell.get() }, comp);
}

#[test]
fn refcell_unsized() {
let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]);
{
let b = &mut *cell.borrow_mut();
b[0] = 4;
b[2] = 5;
}
let comp: &mut [i32] = &mut [4, 2, 5];
assert_eq!(&*cell.borrow(), comp);
}
// FIXME(#25351) needs deeply nested coercions of DST structs.
// #[test]
// fn refcell_unsized() {
// let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]);
// {
// let b = &mut *cell.borrow_mut();
// b[0] = 4;
// b[2] = 5;
// }
// let comp: &mut [i32] = &mut [4, 2, 5];
// assert_eq!(&*cell.borrow(), comp);
// }
2 changes: 0 additions & 2 deletions src/librustc/diagnostics.rs
Expand Up @@ -808,8 +808,6 @@ register_diagnostics! {
E0019,
E0022,
E0038,
E0079, // enum variant: expected signed integer constant
E0080, // enum variant: constant evaluation error
E0109,
E0110,
E0134,
Expand Down
7 changes: 4 additions & 3 deletions src/librustc/middle/traits/select.rs
Expand Up @@ -1369,7 +1369,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn assemble_candidates_for_unsizing(&mut self,
obligation: &TraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>) {
// TODO is it Ok to skip the binder here?
// It is ok to skip past the higher-ranked binders here because the `match`
// below does not consider regions at all.
let source = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
let target = self.infcx.shallow_resolve(obligation.predicate.0.input_types()[0]);

Expand Down Expand Up @@ -1494,7 +1495,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&ClosureCandidate(..) |
&FnPointerCandidate(..) |
&BuiltinObjectCandidate(..) |
&&BuiltinUnsizeCandidate(..) |
&BuiltinUnsizeCandidate(..) |
&DefaultImplObjectCandidate(..) |
&BuiltinCandidate(..) => {
// We have a where-clause so don't go around looking
Expand Down Expand Up @@ -2498,7 +2499,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::lookup_field_type_unsubstituted(tcx, def_id, f.id)
}).collect::<Vec<_>>();

// The last field of the structure has to exist and be a
// FIXME(#25351) The last field of the structure has to exist and be a
// type parameter (for now, to avoid tracking edge cases).
let i = if let Some(&ty::ty_param(p)) = fields.last().map(|ty| &ty.sty) {
assert!(p.space == TypeSpace);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/traits/util.rs
Expand Up @@ -377,7 +377,7 @@ pub fn predicate_for_trait_def<'tcx>(
let trait_ref = ty::TraitRef {
def_id: trait_def_id,
substs: tcx.mk_substs(Substs::new_trait(ty_params, vec![], param_ty))
});
};
predicate_for_trait_ref(cause, trait_ref, recursion_depth)
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty.rs
Expand Up @@ -4420,7 +4420,7 @@ pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
match ty.sty {
ty_uniq(ty) => ty,
ty_rptr(_, mt) |ty_ptr(mt) => mt.ty,
ty_rptr(_, mt) | ty_ptr(mt) => mt.ty,
_ => ty
}
}
Expand Down
8 changes: 5 additions & 3 deletions src/librustc_trans/trans/debuginfo/metadata.rs
Expand Up @@ -1058,6 +1058,7 @@ impl MetadataCreationResult {
}
}

#[derive(Debug)]
enum MemberOffset {
FixedMemberOffset { bytes: usize },
// For ComputedMemberOffset, the offset is read from the llvm type definition.
Expand All @@ -1066,6 +1067,7 @@ enum MemberOffset {

// Description of a type member, which can either be a regular field (as in
// structs or tuples) or an enum variant.
#[derive(Debug)]
struct MemberDescription {
name: String,
llvm_type: Type,
Expand Down Expand Up @@ -1163,13 +1165,13 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
span: Span)
-> RecursiveTypeDescription<'tcx> {
let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
let struct_llvm_type = type_of::type_of(cx, struct_type);
let struct_llvm_type = type_of::in_memory_type_of(cx, struct_type);

let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);

let struct_metadata_stub = create_struct_stub(cx,
struct_llvm_type,
&struct_name[..],
&struct_name,
unique_type_id,
containing_scope);

Expand Down Expand Up @@ -1299,7 +1301,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
set_members_of_composite_type(cx,
variant_type_metadata,
variant_llvm_type,
&member_descriptions[..]);
&member_descriptions);
MemberDescription {
name: "".to_string(),
llvm_type: variant_llvm_type,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/expr.rs
Expand Up @@ -487,11 +487,11 @@ fn coerce_unsized<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let trait_substs = Substs::erased(VecPerParamSpace::new(vec![target.ty],
vec![source.ty],
Vec::new()));
let trait_ref = ty::Binder(Rc::new(ty::TraitRef {
let trait_ref = ty::Binder(ty::TraitRef {
def_id: langcall(bcx, Some(span), "coercion",
CoerceUnsizedTraitLangItem),
substs: bcx.tcx().mk_substs(trait_substs)
}));
});

let kind = match fulfill_obligation(bcx.ccx(), span, trait_ref) {
traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => {
Expand Down
55 changes: 30 additions & 25 deletions src/librustc_typeck/check/cast.rs
Expand Up @@ -60,28 +60,29 @@ pub fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) {
let e = &cast.expr;
let t_e = structurally_resolved_type(fcx, span, cast.expr_ty);
let t_1 = structurally_resolved_type(fcx, span, cast.cast_ty);
let tcx = fcx.tcx();

// Check for trivial casts.
if !ty::type_has_ty_infer(t_1) {
if let Ok(()) = coercion::mk_assignty(fcx, e, t_e, t_1) {
if ty::type_is_numeric(t_1) && ty::type_is_numeric(t_e) {
fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS,
e.id,
span,
format!("trivial numeric cast: `{}` as `{}`. Cast can be \
replaced by coercion, this might require type \
ascription or a temporary variable",
fcx.infcx().ty_to_string(t_e),
fcx.infcx().ty_to_string(t_1)));
tcx.sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS,
e.id,
span,
format!("trivial numeric cast: `{}` as `{}`. Cast can be \
replaced by coercion, this might require type \
ascription or a temporary variable",
fcx.infcx().ty_to_string(t_e),
fcx.infcx().ty_to_string(t_1)));
} else {
fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_CASTS,
e.id,
span,
format!("trivial cast: `{}` as `{}`. Cast can be \
replaced by coercion, this might require type \
ascription or a temporary variable",
fcx.infcx().ty_to_string(t_e),
fcx.infcx().ty_to_string(t_1)));
tcx.sess.add_lint(lint::builtin::TRIVIAL_CASTS,
e.id,
span,
format!("trivial cast: `{}` as `{}`. Cast can be \
replaced by coercion, this might require type \
ascription or a temporary variable",
fcx.infcx().ty_to_string(t_e),
fcx.infcx().ty_to_string(t_1)));
}
return;
}
Expand All @@ -91,14 +92,14 @@ pub fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) {
let t_e_is_scalar = ty::type_is_scalar(t_e);
let t_e_is_integral = ty::type_is_integral(t_e);
let t_e_is_float = ty::type_is_floating_point(t_e);
let t_e_is_c_enum = ty::type_is_c_like_enum(fcx.tcx(), t_e);
let t_e_is_c_enum = ty::type_is_c_like_enum(tcx, t_e);

let t_1_is_scalar = ty::type_is_scalar(t_1);
let t_1_is_integral = ty::type_is_integral(t_1);
let t_1_is_char = ty::type_is_char(t_1);
let t_1_is_bare_fn = ty::type_is_bare_fn(t_1);
let t_1_is_float = ty::type_is_floating_point(t_1);
let t_1_is_c_enum = ty::type_is_c_like_enum(fcx.tcx(), t_1);
let t_1_is_c_enum = ty::type_is_c_like_enum(tcx, t_1);
let t1_is_fat_ptr = fcx.type_is_fat_ptr(t_1, span);

// casts to scalars other than `char` and `bare fn` are trivial
Expand All @@ -114,7 +115,7 @@ pub fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) {
}, t_e, None);
}
} else if t_1.sty == ty::ty_bool {
span_err!(fcx.tcx().sess, span, E0054,
span_err!(tcx.sess, span, E0054,
"cannot cast as `bool`, compare with zero instead");
} else if t_e_is_float && (t_1_is_scalar || t_1_is_c_enum) &&
!(t_1_is_integral || t_1_is_float) {
Expand Down Expand Up @@ -174,12 +175,16 @@ pub fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) {
} else if t1_is_fat_ptr {
// FIXME This should be allowed where the lefthandside is also a fat
// pointer and is the same kind of fat pointer, i.e., array to array,
// trait object to trait object.
fcx.type_error_message(span, |actual| {
format!("cast to fat pointer: `{}` as `{}`",
actual,
fcx.infcx().ty_to_string(t_1))
}, t_e, None);
// trait object to trait object. That is a bit looser than the current
// rquirement that they are pointers to the same type.
if !(fcx.type_is_fat_ptr(t_e, span) &&
ty::deref(t_1, true).unwrap().ty == ty::deref(t_e, true).unwrap().ty) {
fcx.type_error_message(span, |actual| {
format!("cast to fat pointer: `{}` as `{}`",
actual,
fcx.infcx().ty_to_string(t_1))
}, t_e, None);
}
} else if !(t_e_is_scalar && t_1_is_trivial) {
fcx.type_error_message(span, |actual| {
format!("non-scalar cast: `{}` as `{}`",
Expand Down
10 changes: 8 additions & 2 deletions src/librustc_typeck/check/coercion.rs
Expand Up @@ -285,14 +285,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {

// Create an obligation for `Source: CoerceUnsized<Target>`.
let cause = ObligationCause::misc(self.origin.span(), self.fcx.body_id);
queue.push_back(predicate_for_trait_def(self.tcx(), cause, coerce_unsized_did,
0, source, vec![target]));
queue.push_back(predicate_for_trait_def(self.tcx(),
cause,
coerce_unsized_did,
0,
source,
vec![target]));

// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
// inference might unify those two inner type variables later.
let traits = [coerce_unsized_did, unsize_did];
while let Some(obligation) = queue.pop_front() {
debug!("coerce_unsized resolve step: {}", obligation.repr(self.tcx()));
let trait_ref = match obligation.predicate {
ty::Predicate::Trait(ref tr) if traits.contains(&tr.def_id()) => {
tr.clone()
Expand All @@ -305,6 +310,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
match selcx.select(&obligation.with(trait_ref)) {
// Uncertain or unimplemented.
Ok(None) | Err(traits::Unimplemented) => {
debug!("coerce_unsized: early return - can't prove obligation");
return Err(ty::terr_mismatch);
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc_typeck/check/regionck.rs
Expand Up @@ -85,6 +85,7 @@
use astconv::AstConv;
use check::dropck;
use check::FnCtxt;
use middle::free_region::FreeRegionMap;
use middle::implicator;
use middle::mem_categorization as mc;
use middle::region::CodeExtent;
Expand Down

0 comments on commit 5d4cce6

Please sign in to comment.