Skip to content

Commit 1e9ed94

Browse files
committed
rustc compiles. still don't merge
1 parent 6d01883 commit 1e9ed94

File tree

4 files changed

+86
-54
lines changed

4 files changed

+86
-54
lines changed

src/librustc/middle/const_eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ fn cast_const<'tcx>(tcx: &ty::ctxt<'tcx>, val: const_val, ty: Ty) -> CastResult
837837
macro_rules! convert_val {
838838
($intermediate_ty:ty, $const_type:ident, $target_ty:ty) => {
839839
match val {
840-
const_bool(b) => Ok($const_type(b as $intermediate_ty as $target_ty)),
840+
const_bool(b) => Ok($const_type(b as u64 as $intermediate_ty as $target_ty)),
841841
const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)),
842842
const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)),
843843
const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)),

src/librustc/middle/ty.rs

-24
Original file line numberDiff line numberDiff line change
@@ -342,30 +342,6 @@ pub enum AutoAdjustment<'tcx> {
342342
/// }
343343
/// ```
344344
#[derive(Copy, Clone, Debug)]
345-
346-
#[derive(Copy, PartialEq, Eq)]
347-
pub enum UnsizeKind {
348-
Vtable,
349-
Length
350-
}
351-
352-
/// Returns the kind of unsize information of t, or None
353-
/// if t is sized or it is unknown.
354-
pub fn unsize_kind<'tcx>(cx: &ctxt<'tcx>,
355-
t: Ty<'tcx>)
356-
-> Option<UnsizeKind> {
357-
match t.sty {
358-
ty_vec(_, None) => Some(Length),
359-
ty_trait(_) => Some(Vtable),
360-
ty_struct(did, substs) => {
361-
let last_field = struct_fields(cx, did, substs).pop();
362-
last_field.map(|f| unsize_kind(f.mt.ty))
363-
}
364-
_ => None
365-
}
366-
}
367-
368-
#[derive(Clone, Debug)]
369345
pub struct AutoDerefRef<'tcx> {
370346
/// Step 1. Apply a number of dereferences, producing an lvalue.
371347
pub autoderefs: usize,

src/librustc_typeck/check/cast.rs

+85-22
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,27 @@
1414
//! * `e` has type `T` and `T` coerces to `U`; *coercion-cast*
1515
//! * `e` has type `*T`, `U` is `*U_0`, and either `U_0: Sized` or
1616
//! unsize_kind(`T`) = unsize_kind(`U_0`); *ptr-ptr-cast*
17-
//! * `e` has type `*T` and `U` is `usize`, while `T: Sized`; *ptr-addr-cast*
17+
//! * `e` has type `*T` and `U` is a numeric type, while `T: Sized`; *ptr-addr-cast*
1818
//! * `e` has type `usize` and `U` is `*U_0`, while `U_0: Sized`; *addr-ptr-cast*
1919
//! * `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
2020
//! * `e` is a C-like enum and `U` is an integer type or `bool`; *enum-cast*
2121
//! * `e` has type `bool` and `U` is an integer; *bool-cast*
2222
//! * `e` has type `u8` and `U` is `char`; *u8-char-cast*
2323
//! * `e` has type `&.[T; n]` and `U` is `*T`, and `e` is a mutable
2424
//! reference if `U` is. *array-ptr-cast*
25+
//! * `e` is a function pointer type and `U` has type `*T`,
26+
//! while `T: Sized`; *fptr-ptr-cast*
27+
//! * `e` is a function pointer type and `U` is an integer; *fptr-addr-cast*
28+
//!
29+
//! where `&.T` and `*T` are references of either mutability,
30+
//! and where unsize_kind(`T`) is the kind of the unsize info
31+
//! in `T` - a vtable or a length (or `()` if `T: Sized`).
32+
//!
33+
//! Casting is not transitive, that is, even if `e as U1 as U2` is a valid
34+
//! expression, `e as U2` is not necessarily so (in fact it will only be valid if
35+
//! `U1` coerces to `U2`).
2536
2637
use super::coercion;
27-
use super::demand;
2838
use super::FnCtxt;
2939
use super::structurally_resolved_type;
3040

@@ -33,12 +43,10 @@ use middle::infer;
3343
use middle::ty;
3444
use middle::ty::Ty;
3545
use syntax::ast;
36-
use syntax::ast::UintTy::{TyU8, TyUs};
46+
use syntax::ast::UintTy::{TyU8};
3747
use syntax::codemap::Span;
3848
use util::ppaux::Repr;
3949

40-
use std::fmt;
41-
4250
/// Reifies a cast check to be checked once we have full type information for
4351
/// a function context.
4452
pub struct CastCheck<'tcx> {
@@ -62,6 +70,7 @@ enum ETy<'tcx> {
6270
Float,
6371
Bool,
6472
Char,
73+
FPtr,
6574
Ptr(&'tcx ty::mt<'tcx>),
6675
RPtr(&'tcx ty::mt<'tcx>),
6776
}
@@ -79,16 +88,41 @@ impl<'tcx> ETy<'tcx> {
7988
fcx.tcx(), t) => Some(ETy::CEnum),
8089
ty::ty_ptr(ref mt) => Some(ETy::Ptr(mt)),
8190
ty::ty_rptr(_, ref mt) => Some(ETy::RPtr(mt)),
91+
ty::ty_bare_fn(..) => Some(ETy::FPtr),
8292
_ => None,
8393
}
8494
}
8595
}
8696

97+
#[derive(Copy, PartialEq, Eq)]
98+
enum UnsizeKind {
99+
Vtable,
100+
Length
101+
}
102+
103+
/// Returns the kind of unsize information of t, or None
104+
/// if t is sized or it is unknown.
105+
fn unsize_kind<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
106+
t: Ty<'tcx>)
107+
-> Option<UnsizeKind> {
108+
match t.sty {
109+
ty::ty_vec(_, None) => Some(UnsizeKind::Length),
110+
ty::ty_trait(_) => Some(UnsizeKind::Vtable),
111+
ty::ty_struct(did, substs) => {
112+
match ty::struct_fields(fcx.tcx(), did, substs).pop() {
113+
None => None,
114+
Some(f) => unsize_kind(fcx, f.mt.ty)
115+
}
116+
}
117+
_ => None
118+
}
119+
}
87120

88121
#[derive(Copy)]
89122
enum CastError {
90123
CastToBool,
91124
CastToChar,
125+
DifferingKinds,
92126
IllegalCast,
93127
NeedViaPtr,
94128
NeedViaInt,
@@ -149,6 +183,13 @@ impl<'tcx> CastCheck<'tcx> {
149183
fcx.infcx().ty_to_string(self.cast_ty))
150184
}, self.expr_ty, None);
151185
}
186+
CastError::DifferingKinds => {
187+
fcx.type_error_message(self.span, |actual| {
188+
format!("illegal cast: `{}` as `{}`; vtable kinds may not match",
189+
actual,
190+
fcx.infcx().ty_to_string(self.cast_ty))
191+
}, self.expr_ty, None);
192+
}
152193
CastError::RefToMutPtr => {
153194
span_err!(fcx.tcx().sess, self.span, E0188,
154195
"cannot cast an immutable reference to a \
@@ -186,7 +227,7 @@ impl<'tcx> CastCheck<'tcx> {
186227
self.expr_ty = structurally_resolved_type(fcx, self.span, self.expr_ty);
187228
self.cast_ty = structurally_resolved_type(fcx, self.span, self.cast_ty);
188229

189-
println!("cast: {} -> {}", self.expr_ty.repr(fcx.tcx()),
230+
debug!("check_cast({} -> {})", self.expr_ty.repr(fcx.tcx()),
190231
self.cast_ty.repr(fcx.tcx()));
191232

192233
if ty::type_is_error(self.expr_ty) || ty::type_is_error(self.cast_ty) {
@@ -217,17 +258,17 @@ impl<'tcx> CastCheck<'tcx> {
217258

218259
match (t_e, t_1) {
219260
// All non-coercion casts create a true scalar
220-
(_, RPtr(_)) | (_, CEnum) => Err(CastError::NonScalar),
261+
(_, RPtr(_)) | (_, CEnum) | (_, FPtr) => Err(CastError::NonScalar),
221262

222263
(Ptr(m1), Ptr(m2)) => self.check_ptr_ptr_cast(fcx, m1, m2), // ptr-ptr-cast
223-
224-
(Ptr(mt), Int(U(ast::TyUs))) =>
225-
self.check_ptr_addr_cast(fcx, mt), // ptr-addr-cast
226-
(Ptr(_), Int(_)) | (Ptr(_), Float) => Err(CastError::NeedViaUsize),
264+
(Ptr(mt), Int(_)) => self.check_ptr_addr_cast(fcx, mt), // ptr-addr-cast
265+
(Ptr(_), Float) | (FPtr, Float) => Err(CastError::NeedViaUsize),
266+
(FPtr, Int(_)) => Ok(()), // fptr-addr-cast
227267
(RPtr(_), Int(_)) | (RPtr(_), Float) => Err(CastError::NeedViaPtr),
228-
(Int(U(ast::TyUs)), Ptr(mt)) =>
229-
self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
230-
(Int(_), Ptr(_)) | (Float, Ptr(_)) => Err(CastError::NeedViaUsize),
268+
269+
(Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
270+
(FPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
271+
(Float, Ptr(_)) => Err(CastError::NeedViaUsize),
231272

232273
(CEnum, Bool) | (CEnum, Int(_)) => Ok(()), // enum-cast
233274
(_, Bool) => Err(CastError::CastToBool),
@@ -247,20 +288,42 @@ impl<'tcx> CastCheck<'tcx> {
247288
(Bool, Ptr(_)) | (CEnum, Ptr(_)) | (Char, Ptr(_))
248289
=> Err(CastError::NeedViaUsize),
249290

250-
251291
(RPtr(rmt), Ptr(mt)) => self.check_ref_cast(fcx, rmt, mt), // array-ptr-cast
252292
}
253293
}
254294

255295
fn check_ptr_ptr_cast<'a>(&self,
256-
_fcx: &FnCtxt<'a, 'tcx>,
257-
_m_e: &'tcx ty::mt<'tcx>,
258-
_m_1: &'tcx ty::mt<'tcx>)
296+
fcx: &FnCtxt<'a, 'tcx>,
297+
m_e: &'tcx ty::mt<'tcx>,
298+
m_1: &'tcx ty::mt<'tcx>)
259299
-> Result<(), CastError>
260300
{
261301
// ptr-ptr cast. vtables must match.
262-
// TODO: implement
263-
Ok(())
302+
303+
// Cast to sized is OK
304+
if fcx.type_is_known_to_be_sized(m_1.ty, self.span) {
305+
return Ok(());
306+
}
307+
308+
// vtable kinds must match
309+
match (unsize_kind(fcx, m_1.ty), unsize_kind(fcx, m_e.ty)) {
310+
(Some(a), Some(b)) if a == b => Ok(()),
311+
_ => Err(CastError::DifferingKinds)
312+
}
313+
}
314+
315+
fn check_fptr_ptr_cast<'a>(&self,
316+
fcx: &FnCtxt<'a, 'tcx>,
317+
m_1: &'tcx ty::mt<'tcx>)
318+
-> Result<(), CastError>
319+
{
320+
// fptr-ptr cast. must be to sized ptr
321+
322+
if fcx.type_is_known_to_be_sized(m_1.ty, self.span) {
323+
Ok(())
324+
} else {
325+
Err(CastError::IllegalCast)
326+
}
264327
}
265328

266329
fn check_ref_cast<'a>(&self,
@@ -294,7 +357,7 @@ impl<'tcx> CastCheck<'tcx> {
294357
Err(CastError::IllegalCast)
295358
}
296359

297-
fn check_ptr_addr_cast<'a>(&self,
360+
fn check_addr_ptr_cast<'a>(&self,
298361
fcx: &FnCtxt<'a, 'tcx>,
299362
m_1: &'tcx ty::mt<'tcx>)
300363
-> Result<(), CastError>
@@ -307,7 +370,7 @@ impl<'tcx> CastCheck<'tcx> {
307370
}
308371
}
309372

310-
fn check_addr_ptr_cast<'a>(&self,
373+
fn check_ptr_addr_cast<'a>(&self,
311374
fcx: &FnCtxt<'a, 'tcx>,
312375
m_e: &'tcx ty::mt<'tcx>)
313376
-> Result<(), CastError>

src/librustc_typeck/check/mod.rs

-7
Original file line numberDiff line numberDiff line change
@@ -1509,13 +1509,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15091509
span)
15101510
}
15111511

1512-
pub fn type_is_fat_ptr(&self, ty: Ty<'tcx>, span: Span) -> bool {
1513-
if let Some(mt) = ty::deref(ty, true) {
1514-
return !self.type_is_known_to_be_sized(mt.ty, span);
1515-
}
1516-
false
1517-
}
1518-
15191512
pub fn register_builtin_bound(&self,
15201513
ty: Ty<'tcx>,
15211514
builtin_bound: ty::BuiltinBound,

0 commit comments

Comments
 (0)