Skip to content

Commit c5f6f84

Browse files
committed
Introduce a built-in Unsize trait and use it for unsizing in coercions.
1 parent 7786e14 commit c5f6f84

20 files changed

+482
-381
lines changed

src/libcore/marker.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ pub trait Sized : MarkerTrait {
5353
// Empty.
5454
}
5555

56+
/// Types that can be "unsized" to a dynamically sized type.
57+
#[unstable(feature = "core")]
58+
#[cfg(not(stage0))] // SNAP c64d671
59+
#[lang="unsize"]
60+
pub trait Unsize<T> : PhantomFn<Self, T> {
61+
// Empty.
62+
}
63+
5664
/// Types that can be copied by simply copying bits (i.e. `memcpy`).
5765
///
5866
/// By default, variable bindings have 'move semantics.' In other

src/librustc/diagnostics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ register_diagnostics! {
6868
E0019,
6969
E0020,
7070
E0022,
71+
E0038,
7172
E0109,
7273
E0110,
7374
E0133,

src/librustc/middle/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ lets_do_this! {
259259

260260
SendTraitLangItem, "send", send_trait;
261261
SizedTraitLangItem, "sized", sized_trait;
262+
UnsizeTraitLangItem, "unsize", unsize_trait;
262263
CopyTraitLangItem, "copy", copy_trait;
263264
SyncTraitLangItem, "sync", sync_trait;
264265

src/librustc/middle/traits/error_reporting.rs

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ use super::{
1515
Obligation,
1616
ObligationCauseCode,
1717
OutputTypeParameterMismatch,
18+
TraitNotObjectSafe,
1819
PredicateObligation,
1920
SelectionError,
21+
ObjectSafetyViolation,
22+
MethodViolationCode,
23+
object_safety_violations,
2024
};
2125

2226
use fmt_macros::{Parser, Piece, Position};
@@ -246,6 +250,55 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
246250
note_obligation_cause(infcx, obligation);
247251
}
248252
}
253+
254+
TraitNotObjectSafe(ref trait_ref) => {
255+
span_err!(infcx.tcx.sess, obligation.cause.span, E0038,
256+
"cannot convert to a trait object because trait `{}` is not object-safe",
257+
ty::item_path_str(infcx.tcx, trait_ref.def_id()));
258+
259+
for violation in object_safety_violations(infcx.tcx, trait_ref.clone()) {
260+
match violation {
261+
ObjectSafetyViolation::SizedSelf => {
262+
infcx.tcx.sess.span_note(
263+
obligation.cause.span,
264+
"the trait cannot require that `Self : Sized`");
265+
}
266+
267+
ObjectSafetyViolation::SupertraitSelf => {
268+
infcx.tcx.sess.span_note(
269+
obligation.cause.span,
270+
"the trait cannot use `Self` as a type parameter \
271+
in the supertrait listing");
272+
}
273+
274+
ObjectSafetyViolation::Method(method,
275+
MethodViolationCode::StaticMethod) => {
276+
infcx.tcx.sess.span_note(
277+
obligation.cause.span,
278+
&format!("method `{}` has no receiver",
279+
method.name.user_string(infcx.tcx)));
280+
}
281+
282+
ObjectSafetyViolation::Method(method,
283+
MethodViolationCode::ReferencesSelf) => {
284+
infcx.tcx.sess.span_note(
285+
obligation.cause.span,
286+
&format!("method `{}` references the `Self` type \
287+
in its arguments or return type",
288+
method.name.user_string(infcx.tcx)));
289+
}
290+
291+
ObjectSafetyViolation::Method(method,
292+
MethodViolationCode::Generic) => {
293+
infcx.tcx.sess.span_note(
294+
obligation.cause.span,
295+
&format!("method `{}` has generic type parameters",
296+
method.name.user_string(infcx.tcx)));
297+
}
298+
}
299+
}
300+
301+
}
249302
}
250303
}
251304

@@ -397,10 +450,6 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
397450
"only the last field of a struct or enum variant \
398451
may have a dynamically sized type")
399452
}
400-
ObligationCauseCode::ObjectSized => {
401-
span_note!(tcx.sess, cause_span,
402-
"only sized types can be made into objects");
403-
}
404453
ObligationCauseCode::SharedStatic => {
405454
span_note!(tcx.sess, cause_span,
406455
"shared static variables must have a type that implements `Sync`");

src/librustc/middle/traits/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use util::ppaux::Repr;
2727

2828
pub use self::error_reporting::report_fulfillment_errors;
2929
pub use self::error_reporting::report_overflow_error;
30+
pub use self::error_reporting::report_selection_error;
3031
pub use self::error_reporting::suggest_new_overflow_limit;
3132
pub use self::coherence::orphan_check;
3233
pub use self::coherence::overlapping_impls;
@@ -46,6 +47,7 @@ pub use self::select::{MethodMatchedData}; // intentionally don't export variant
4647
pub use self::util::elaborate_predicates;
4748
pub use self::util::get_vtable_index_of_object_method;
4849
pub use self::util::trait_ref_for_builtin_bound;
50+
pub use self::util::predicate_for_trait_def;
4951
pub use self::util::supertraits;
5052
pub use self::util::Supertraits;
5153
pub use self::util::transitive_bounds;
@@ -117,9 +119,6 @@ pub enum ObligationCauseCode<'tcx> {
117119
// Types of fields (other than the last) in a struct must be sized.
118120
FieldSized,
119121

120-
// Only Sized types can be made into objects
121-
ObjectSized,
122-
123122
// static items must have `Sync` type
124123
SharedStatic,
125124

@@ -155,6 +154,7 @@ pub enum SelectionError<'tcx> {
155154
OutputTypeParameterMismatch(ty::PolyTraitRef<'tcx>,
156155
ty::PolyTraitRef<'tcx>,
157156
ty::type_err<'tcx>),
157+
TraitNotObjectSafe(ty::PolyTraitRef<'tcx>),
158158
}
159159

160160
pub struct FulfillmentError<'tcx> {
@@ -531,7 +531,9 @@ impl<'tcx, N> Vtable<'tcx, N> {
531531
}
532532
}
533533

534-
pub fn map_nested<M, F>(&self, op: F) -> Vtable<'tcx, M> where F: FnMut(&N) -> M {
534+
pub fn map_nested<M, F>(&self, op: F) -> Vtable<'tcx, M> where
535+
F: FnMut(&N) -> M,
536+
{
535537
match *self {
536538
VtableImpl(ref i) => VtableImpl(i.map_nested(op)),
537539
VtableDefaultImpl(ref t) => VtableDefaultImpl(t.map_nested(op)),

0 commit comments

Comments
 (0)