.map(|x| *x).collect();
ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
}
- ast::ItemTrait(ref a, b, ref c, ref methods) => {
+ ast::ItemTrait(ref a, ref b, ref c, ref methods) => {
let methods = methods.iter()
.filter(|m| trait_method_in_cfg(cx, *m) )
.map(|x| (*x).clone())
.collect();
- ast::ItemTrait((*a).clone(), b, (*c).clone(), methods)
+ ast::ItemTrait((*a).clone(), (*b).clone(), (*c).clone(), methods)
}
ast::ItemStruct(ref def, ref generics) => {
ast::ItemStruct(fold_struct(cx, &**def), generics.clone())
}
}
-fn item_sized(item: ebml::Doc) -> ast::Sized {
- match reader::maybe_get_doc(item, tag_items_data_item_sized) {
- None => ast::StaticSize,
- Some(sized_doc) => {
- match reader::doc_as_u8(sized_doc) as char {
- 'd' => ast::DynSize,
- 's' => ast::StaticSize,
- _ => fail!("unknown sized-ness character")
- }
- }
- }
-}
-
fn item_method_sort(item: ebml::Doc) -> char {
let mut ret = 'r';
reader::tagged_docs(item, tag_item_trait_method_sort, |doc| {
let tp_defs = item_ty_param_defs(item_doc, tcx, cdata,
tag_items_data_item_ty_param_bounds);
let rp_defs = item_region_param_defs(item_doc, cdata);
- let sized = item_sized(item_doc);
let mut bounds = ty::empty_builtin_bounds();
// Collect the builtin bounds from the encoded supertraits.
// FIXME(#8559): They should be encoded directly.
});
true
});
- // Turn sized into a bound, FIXME(#8559).
- if sized == ast::StaticSize {
- tcx.lang_items.to_builtin_kind(tcx.lang_items.sized_trait().unwrap()).map(|bound| {
- bounds.add(bound);
- });
- }
ty::TraitDef {
generics: ty::Generics {types: tp_defs,
}
}
-fn encode_sized(ebml_w: &mut Encoder, sized: Sized) {
- ebml_w.start_tag(tag_items_data_item_sized);
- let ch = match sized {
- DynSize => 'd',
- StaticSize => 's',
- };
- ebml_w.wr_str(str::from_char(ch).as_slice());
- ebml_w.end_tag();
-}
-
fn encode_stability(ebml_w: &mut Encoder, stab_opt: Option<attr::Stability>) {
stab_opt.map(|stab| {
ebml_w.start_tag(tag_items_data_item_stability);
ast_method)
}
}
- ItemTrait(_, sized, ref super_traits, ref ms) => {
+ ItemTrait(_, _, ref super_traits, ref ms) => {
add_to_index(item, ebml_w, index);
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, def_id);
encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
encode_name(ebml_w, item.ident.name);
encode_attributes(ebml_w, item.attrs.as_slice());
- // When we fix the rest of the supertrait nastiness (FIXME(#8559)), we
- // should no longer need this ugly little hack either.
- encode_sized(ebml_w, sized);
encode_visibility(ebml_w, vis);
encode_stability(ebml_w, stab);
for &method_def_id in ty::trait_method_def_ids(tcx, def_id).iter() {
item.id,
ItemRibKind),
|this| {
+ this.resolve_type_parameters(&generics.ty_params);
visit::walk_item(this, item, ());
});
}
methods.as_slice());
}
- ItemTrait(ref generics, _, ref traits, ref methods) => {
+ ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
// Create a new rib for the self type.
let self_type_rib = Rib::new(ItemRibKind);
for trt in traits.iter() {
this.resolve_trait_reference(item.id, trt, TraitDerivation);
}
+ match unbound {
+ &Some(ast::TraitTyParamBound(ref tpb)) => {
+ this.resolve_trait_reference(item.id, tpb, TraitDerivation);
+ }
+ _ => {}
+ }
for method in (*methods).iter() {
// Create a new rib for the method-specific type
}
fn resolve_type_parameters(&mut self,
- type_parameters: &OwnedSlice<TyParam>) {
+ type_parameters: &OwnedSlice<TyParam>) {
for type_parameter in type_parameters.iter() {
for bound in type_parameter.bounds.iter() {
self.resolve_type_parameter_bound(type_parameter.id, bound);
}
+ match &type_parameter.unbound {
+ &Some(ref unbound) => self.resolve_type_parameter_bound(type_parameter.id, unbound),
+ &None => {}
+ }
match type_parameter.default {
Some(ref ty) => self.resolve_type(&**ty),
None => {}
}
fn resolve_trait_reference(&mut self,
- id: NodeId,
- trait_reference: &TraitRef,
- reference_type: TraitReferenceType) {
+ id: NodeId,
+ trait_reference: &TraitRef,
+ reference_type: TraitReferenceType) {
match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
None => {
let path_str = self.path_idents_to_str(&trait_reference.path);
_ => {}
}
- let (generics, sized, supertraits) = match it.node {
- ast::ItemTrait(ref generics, sized, ref supertraits, _) => {
- (generics, sized, supertraits)
+ let (generics, unbound, supertraits) = match it.node {
+ ast::ItemTrait(ref generics, ref unbound, ref supertraits, _) => {
+ (generics, unbound, supertraits)
}
ref s => {
tcx.sess.span_bug(
generics);
let builtin_bounds =
- ensure_supertraits(ccx, it.id, it.span, supertraits, sized);
+ ensure_supertraits(ccx, it.id, it.span, supertraits, unbound);
let substs = mk_item_substs(ccx, &ty_generics);
let trait_def = Rc::new(ty::TraitDef {
id: ast::NodeId,
sp: codemap::Span,
ast_trait_refs: &Vec<ast::TraitRef>,
- sized: ast::Sized)
+ unbound: &Option<ast::TyParamBound>)
-> ty::BuiltinBounds
{
let tcx = ccx.tcx;
}
}
- if sized == ast::StaticSize {
- match tcx.lang_items.require(SizedTraitLangItem) {
- Ok(def_id) => {
- ty::try_add_builtin_trait(tcx, def_id, &mut bounds);
- }
- Err(s) => tcx.sess.err(s.as_slice()),
- };
- }
-
+ add_unsized_bound(ccx, unbound, &mut bounds, "trait", sp);
tcx.supertraits.borrow_mut().insert(local_def(id),
Rc::new(ty_trait_refs));
bounds
&generics.ty_params, base_generics)
}
+// Add the Sized bound, unless the type parameter is marked as `Sized?`.
+fn add_unsized_bound(ccx: &CrateCtxt,
+ unbound: &Option<ast::TyParamBound>,
+ bounds: &mut ty::BuiltinBounds,
+ desc: &str,
+ span: Span) {
+ let kind_id = ccx.tcx.lang_items.require(SizedTraitLangItem);
+ match unbound {
+ &Some(TraitTyParamBound(ref tpb)) => {
+ // #FIXME(8559) currently requires the unbound to be built-in.
+ let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, tpb);
+ match kind_id {
+ Ok(kind_id) if trait_def_id != kind_id => {
+ ccx.tcx.sess.span_warn(span,
+ format!("default bound relaxed \
+ for a {}, but this does \
+ nothing because the given \
+ bound is not a default. \
+ Only `Sized?` is supported.",
+ desc).as_slice());
+ ty::try_add_builtin_trait(ccx.tcx,
+ kind_id,
+ bounds);
+ }
+ _ => {}
+ }
+ }
+ _ if kind_id.is_ok() => {
+ ty::try_add_builtin_trait(ccx.tcx,
+ kind_id.unwrap(),
+ bounds);
+ }
+ // No lang item for Sized, so we can't add it as a bound.
+ _ => {}
+ }
+}
+
fn ty_generics(ccx: &CrateCtxt,
space: subst::ParamSpace,
lifetimes: &Vec<ast::Lifetime>,
let bounds = Rc::new(compute_bounds(ccx,
param_ty,
¶m.bounds,
- param.sized,
+ ¶m.unbound,
param.ident,
param.span));
let default = param.default.map(|path| {
ccx: &CrateCtxt,
param_ty: ty::ParamTy,
ast_bounds: &OwnedSlice<ast::TyParamBound>,
- sized: ast::Sized,
+ unbound: &Option<ast::TyParamBound>,
ident: ast::Ident,
span: Span) -> ty::ParamBounds
{
}
}
- if sized == ast::StaticSize {
- match ccx.tcx.lang_items.require(SizedTraitLangItem) {
- Ok(def_id) => { ty::try_add_builtin_trait(ccx.tcx,
- def_id,
- &mut param_bounds.builtin_bounds); },
- // Fixme(13367) after `type` makes it into the snapshot, we can check this properly
- Err(_s) => {}, //ccx.tcx.sess.err(s),
- }
- }
+ add_unsized_bound(ccx,
+ unbound,
+ &mut param_bounds.builtin_bounds,
+ "type parameter",
+ span);
check_bounds_compatible(ccx.tcx, ¶m_bounds, ident, span);
ident: ty_param.ident,
id: ty_param.id,
bounds: bounds,
+ unbound: ty_param.unbound.clone(),
default: ty_param.default,
span: ty_param.span,
- sized: ty_param.sized,
}
})
}
// miscellaneous, no highlighting
t::DOT | t::DOTDOT | t::DOTDOTDOT | t::COMMA | t::SEMI |
t::COLON | t::MOD_SEP | t::LARROW | t::LPAREN |
- t::RPAREN | t::LBRACKET | t::LBRACE | t::RBRACE => "",
+ t::RPAREN | t::LBRACKET | t::LBRACE | t::RBRACE | t::QUESTION => "",
t::DOLLAR => {
if t::is_ident(&lexer.peek().tok) {
is_macro_nonterminal = true;
pub struct TyParam {
pub ident: Ident,
pub id: NodeId,
- pub sized: Sized,
pub bounds: OwnedSlice<TyParamBound>,
+ pub unbound: Option<TyParamBound>,
pub default: Option<P<Ty>>,
pub span: Span
}
}
}
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
-pub enum Sized {
- DynSize,
- StaticSize,
-}
-
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct StructField_ {
pub kind: StructFieldKind,
ItemEnum(EnumDef, Generics),
ItemStruct(Gc<StructDef>, Generics),
/// Represents a Trait Declaration
- ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ),
+ ItemTrait(Generics,
+ Option<TyParamBound>, // (optional) default bound not required for Self.
+ // Currently, only Sized makes sense here.
+ Vec<TraitRef> ,
+ Vec<TraitMethod>),
ItemImpl(Generics,
Option<TraitRef>, // (optional) trait this impl implements
P<Ty>, // self
fn typaram(&self,
span: Span,
id: ast::Ident,
- sized: ast::Sized,
bounds: OwnedSlice<ast::TyParamBound>,
+ unbound: Option<ast::TyParamBound>,
default: Option<P<ast::Ty>>) -> ast::TyParam;
fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
fn typaram(&self,
span: Span,
id: ast::Ident,
- sized: ast::Sized,
bounds: OwnedSlice<ast::TyParamBound>,
+ unbound: Option<ast::TyParamBound>,
default: Option<P<ast::Ty>>) -> ast::TyParam {
ast::TyParam {
ident: id,
id: ast::DUMMY_NODE_ID,
- sized: sized,
bounds: bounds,
+ unbound: unbound,
default: default,
span: span
}
fn strip_bounds(&self, generics: &Generics) -> Generics {
let new_params = generics.ty_params.map(|ty_param| {
- ast::TyParam { bounds: OwnedSlice::empty(), ..*ty_param }
+ ast::TyParam { bounds: OwnedSlice::empty(), unbound: None, ..*ty_param }
});
Generics {
ty_params: new_params,
encodable.rs for more.
*/
-use ast;
use ast::{MetaItem, Item, Expr, MutMutable, Ident};
use codemap::Span;
use ext::base::ExtCtxt;
additional_bounds: Vec::new(),
generics: LifetimeBounds {
lifetimes: Vec::new(),
- bounds: vec!(("__D", ast::StaticSize, vec!(Path::new_(
+ bounds: vec!(("__D", None, vec!(Path::new_(
vec!("serialize", "Decoder"), None,
vec!(box Literal(Path::new_local("__E"))), true))),
- ("__E", ast::StaticSize, vec!()))
+ ("__E", None, vec!()))
},
methods: vec!(
MethodDef {
```
*/
-use ast;
use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil};
use codemap::Span;
use ext::base::ExtCtxt;
additional_bounds: Vec::new(),
generics: LifetimeBounds {
lifetimes: Vec::new(),
- bounds: vec!(("__S", ast::StaticSize, vec!(Path::new_(
+ bounds: vec!(("__S", None, vec!(Path::new_(
vec!("serialize", "Encoder"), None,
vec!(box Literal(Path::new_local("__E"))), true))),
- ("__E", ast::StaticSize, vec!()))
+ ("__E", None, vec!()))
},
methods: vec!(
MethodDef {
cx.typaram(self.span,
ty_param.ident,
- ty_param.sized,
OwnedSlice::from_vec(bounds),
+ ty_param.unbound.clone(),
None)
}));
let trait_generics = Generics {
}
-fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, sized: ast::Sized, bounds: &[Path],
+fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str,
+ bounds: &[Path], unbound: Option<ast::TyParamBound>,
self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
let bounds =
bounds.iter().map(|b| {
let path = b.to_path(cx, span, self_ident, self_generics);
cx.typarambound(path)
}).collect();
- cx.typaram(span, cx.ident_of(name), sized, bounds, None)
+ cx.typaram(span, cx.ident_of(name), bounds, unbound, None)
}
-fn mk_generics(lifetimes: Vec<ast::Lifetime> , ty_params: Vec<ast::TyParam> ) -> Generics {
+fn mk_generics(lifetimes: Vec<ast::Lifetime>, ty_params: Vec<ast::TyParam> ) -> Generics {
Generics {
lifetimes: lifetimes,
ty_params: OwnedSlice::from_vec(ty_params)
/// Lifetimes and bounds on type parameters
pub struct LifetimeBounds<'a> {
pub lifetimes: Vec<&'a str>,
- pub bounds: Vec<(&'a str, ast::Sized, Vec<Path<'a>>)>,
+ pub bounds: Vec<(&'a str, Option<ast::TyParamBound>, Vec<Path<'a>>)>,
}
impl<'a> LifetimeBounds<'a> {
}).collect();
let ty_params = self.bounds.iter().map(|t| {
match t {
- &(ref name, sized, ref bounds) => {
+ &(ref name, ref unbound, ref bounds) => {
mk_ty_param(cx,
span,
*name,
- sized,
bounds.as_slice(),
+ unbound.clone(),
self_ty,
self_generics)
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use ast;
use ast::{MetaItem, Item, Expr, MutMutable};
use codemap::Span;
use ext::base::ExtCtxt;
vec!(box Literal(Path::new_local("__S"))), true),
LifetimeBounds {
lifetimes: Vec::new(),
- bounds: vec!(("__S", ast::StaticSize,
+ bounds: vec!(("__S", None,
vec!(Path::new(vec!("std", "hash", "Writer"))))),
},
Path::new_local("__S"))
generics: LifetimeBounds {
lifetimes: Vec::new(),
bounds: vec!(("R",
- ast::StaticSize,
+ None,
vec!( Path::new(vec!("std", "rand", "Rng")) )))
},
explicit_self: None,
TyParam {
ident: tp.ident,
id: id,
- sized: tp.sized,
bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
+ unbound: tp.unbound.as_ref().map(|x| fold_ty_param_bound(x, fld)),
default: tp.default.map(|x| fld.fold_ty(x)),
span: tp.span
}
methods.iter().map(|x| folder.fold_method(*x)).collect()
)
}
- ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
+ ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
let methods = methods.iter().map(|method| {
match *method {
Required(ref m) => Required(folder.fold_type_method(m)),
}
}).collect();
ItemTrait(fold_generics(generics, folder),
- *sized,
+ unbound.clone(),
traits.iter().map(|p| fold_trait_ref(p, folder)).collect(),
methods)
}
'@' => { self.bump(); return token::AT; }
'#' => { self.bump(); return token::POUND; }
'~' => { self.bump(); return token::TILDE; }
+ '?' => { self.bump(); return token::QUESTION; }
':' => {
self.bump();
if self.curr_is(':') {
use ast::{PatTup, PatBox, PatWild, PatWildMulti};
use ast::{BiRem, Required};
use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
-use ast::{Sized, DynSize, StaticSize};
use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
use ast::{StructVariantKind, BiSub};
use ast::StrStyle;
return (ret_lifetime, OwnedSlice::from_vec(result));
}
- // matches typaram = type? IDENT optbounds ( EQ ty )?
+ fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef {
+ let segment = ast::PathSegment {
+ identifier: ident,
+ lifetimes: Vec::new(),
+ types: OwnedSlice::empty(),
+ };
+ let path = ast::Path {
+ span: span,
+ global: false,
+ segments: vec![segment],
+ };
+ ast::TraitRef {
+ path: path,
+ ref_id: ast::DUMMY_NODE_ID,
+ }
+ }
+
+ // matches typaram = (unbound`?`)? IDENT optbounds ( EQ ty )?
fn parse_ty_param(&mut self) -> TyParam {
- let sized = self.parse_sized();
- let span = self.span;
- let ident = self.parse_ident();
+ // This is a bit hacky. Currently we are only interested in a single
+ // unbound, and it may only be `Sized`. To avoid backtracking and other
+ // complications, we parse an ident, then check for `?`. If we find it,
+ // we use the ident as the unbound, otherwise, we use it as the name of
+ // type param.
+ let mut span = self.span;
+ let mut ident = self.parse_ident();
+ let mut unbound = None;
+ if self.eat(&token::QUESTION) {
+ let tref = Parser::trait_ref_from_ident(ident, span);
+ unbound = Some(TraitTyParamBound(tref));
+ span = self.span;
+ ident = self.parse_ident();
+ }
+
let opt_bounds = {
if self.eat(&token::COLON) {
let (_, bounds) = self.parse_ty_param_bounds(false);
TyParam {
ident: ident,
id: ast::DUMMY_NODE_ID,
- sized: sized,
bounds: bounds,
+ unbound: unbound,
default: default,
span: span,
}
else { Inherited }
}
- fn parse_sized(&mut self) -> Sized {
- if self.eat_keyword(keywords::Type) { DynSize }
- else { StaticSize }
- }
-
- fn parse_for_sized(&mut self) -> Sized {
+ fn parse_for_sized(&mut self) -> Option<ast::TyParamBound> {
if self.eat_keyword(keywords::For) {
- if !self.eat_keyword(keywords::Type) {
- let last_span = self.last_span;
- self.span_err(last_span,
- "expected 'type' after for in trait item");
+ let span = self.span;
+ let ident = self.parse_ident();
+ if !self.eat(&token::QUESTION) {
+ self.span_err(span,
+ "expected 'Sized?' after `for` in trait item");
+ return None;
}
- DynSize
+ let tref = Parser::trait_ref_from_ident(ident, span);
+ Some(TraitTyParamBound(tref))
} else {
- StaticSize
+ None
}
}
RBRACE,
POUND,
DOLLAR,
+ QUESTION,
/* Literals */
LIT_BYTE(u8),
RBRACE => "}".to_string(),
POUND => "#".to_string(),
DOLLAR => "$".to_string(),
+ QUESTION => "?".to_string(),
/* Literals */
LIT_BYTE(b) => {
}
try!(self.bclose(item.span));
}
- ast::ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
+ ast::ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
try!(self.head(visibility_qualified(item.vis,
"trait").as_slice()));
try!(self.print_ident(item.ident));
try!(self.print_generics(generics));
- if *sized == ast::DynSize {
- try!(space(&mut self.s));
- try!(word(&mut self.s, "for type"));
+ match unbound {
+ &Some(TraitTyParamBound(ref tref)) => {
+ try!(space(&mut self.s));
+ try!(self.word_space("for"));
+ try!(self.print_trait_ref(tref));
+ try!(word(&mut self.s, "?"));
+ }
+ _ => {}
}
if traits.len() != 0u {
try!(word(&mut self.s, ":"));
} else {
let idx = idx - generics.lifetimes.len();
let param = generics.ty_params.get(idx);
- if param.sized == ast::DynSize {
- try!(s.word_space("type"));
+ match param.unbound {
+ Some(TraitTyParamBound(ref tref)) => {
+ try!(s.print_trait_ref(tref));
+ try!(s.word_space("?"));
+ }
+ _ => {}
}
try!(s.print_ident(param.ident));
try!(s.print_bounds(&None,
// error-pattern: instantiating a type parameter with an incompatible type
fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<T>() }
+fn foo<Sized? T>() { bar::<T>() }
fn main() { }
// error-pattern: instantiating a type parameter with an incompatible type
fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<Option<T>>() }
+fn foo<Sized? T>() { bar::<Option<T>>() }
fn main() { }
struct Foo<T> { data: T }
fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<Foo<T>>() }
+fn foo<Sized? T>() { bar::<Foo<T>>() }
fn main() { }
// Unbounded.
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
f2::<X>(x); //~ ERROR instantiating a type parameter with an incompatible type `X`, which does n
}
fn f2<X>(x: &X) {
}
// Bounded.
-trait T for type {}
-fn f3<type X: T>(x: &X) {
+trait T for Sized? {}
+fn f3<Sized? X: T>(x: &X) {
f4::<X>(x); //~ ERROR instantiating a type parameter with an incompatible type `X`, which does n
}
fn f4<X: T>(x: &X) {
}
// Test with unsized enum.
-enum E<type X> {
+enum E<Sized? X> {
V(X),
}
fn f5<Y>(x: &Y) {}
-fn f6<type X>(x: &X) {}
-fn f7<type X>(x1: &E<X>, x2: &E<X>) {
+fn f6<Sized? X>(x: &X) {}
+fn f7<Sized? X>(x1: &E<X>, x2: &E<X>) {
f5(x1); //~ERROR instantiating a type parameter with an incompatible type `E<X>`, which does not
f6(x2); // ok
}
// Test with unsized struct.
-struct S<type X> {
+struct S<Sized? X> {
x: X,
}
-fn f8<type X>(x1: &S<X>, x2: &S<X>) {
+fn f8<Sized? X>(x1: &S<X>, x2: &S<X>) {
f5(x1); //~ERROR instantiating a type parameter with an incompatible type `S<X>`, which does not
f6(x2); // ok
}
// Test some tuples.
-fn f9<type X>(x1: Box<S<X>>, x2: Box<E<X>>) {
+fn f9<Sized? X>(x1: Box<S<X>>, x2: Box<E<X>>) {
f5(&(*x1, 34i)); //~ERROR instantiating a type parameter with an incompatible type `(S<X>,int)`,
f5(&(32i, *x2)); //~ERROR instantiating a type parameter with an incompatible type `(int,E<X>)`,
}
// impl - bounded
trait T1<Z: T> {
}
-struct S3<type Y>;
-impl<type X: T> T1<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type
+struct S3<Sized? Y>;
+impl<Sized? X: T> T1<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type
}
// impl - unbounded
trait T2<Z> {
}
-impl<type X> T2<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type `X`
+impl<Sized? X> T2<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type `X
// impl - struct
-trait T3<type Z> {
+trait T3<Sized? Z> {
}
struct S4<Y>;
-impl<type X> T3<X> for S4<X> { //ERROR instantiating a type parameter with an incompatible type `X`
+impl<Sized? X> T3<X> for S4<X> { //ERROR instantiating a type parameter with an incompatible type `X
}
*/
// Test that bounds are sized-compatible.
trait T {}
-fn f<type Y: T>() {
+fn f<Sized? Y: T>() {
//~^ERROR incompatible bounds on type parameter Y, bound T does not allow unsized type
}
// except according to those terms.
#![feature(struct_variant)]
-// Test `type` types not allowed in fields.
+// Test `Sized?` types not allowed in fields.
-struct S1<type X> {
+struct S1<Sized? X> {
f1: X, //~ ERROR type `f1` is dynamically sized. dynamically sized types may only appear as the
f2: int,
}
-struct S2<type X> {
+struct S2<Sized? X> {
f: int,
g: X, //~ ERROR type `g` is dynamically sized. dynamically sized types may only appear as the ty
h: int,
}
-enum E<type X> {
+enum E<Sized? X> {
V1(X, int), //~ERROR type `X` is dynamically sized. dynamically sized types may only appear as t
V2{f1: X, f: int}, //~ERROR type `f1` is dynamically sized. dynamically sized types may only app
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// Test `type` local variables.
+// Test `Sized?` local variables.
-trait T for type {}
+trait T for Sized? {}
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
let _: X; //~ERROR variable `_` has dynamically sized type `X`
let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
let y: X; //~ERROR variable `y` has dynamically sized type `X`
let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
}
-fn f2<type X: T>(x: &X) {
+fn f2<Sized? X: T>(x: &X) {
let _: X; //~ERROR variable `_` has dynamically sized type `X`
let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
let y: X; //~ERROR variable `y` has dynamically sized type `X`
let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
}
-fn f3<type X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f3<Sized? X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
let y: X = *x1; //~ERROR variable `y` has dynamically sized type `X`
let y = *x2; //~ERROR variable `y` has dynamically sized type `X`
let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
}
-fn f4<type X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f4<Sized? X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
let y: X = *x1; //~ERROR variable `y` has dynamically sized type `X`
let y = *x2; //~ERROR variable `y` has dynamically sized type `X`
let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
}
-fn g1<type X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
-fn g2<type X: T>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+fn g1<Sized? X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+fn g2<Sized? X: T>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
pub fn main() {
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// Test syntax checks for `type` keyword.
+// Test syntax checks for `Sized?` syntax.
-trait T1 for type {}
-pub trait T2 for type {}
-trait T3<X: T1> for type: T2 {}
-trait T4<type X> {}
-trait T5<type X, Y> {}
-trait T6<Y, type X> {}
-trait T7<type X, type Y> {}
-trait T8<type X: T2> {}
-struct S1<type X>;
-enum E<type X> {}
-impl <type X> T1 for S1<X> {}
-fn f<type X>() {}
+trait T1 for Sized? {}
+pub trait T2 for Sized? {}
+trait T3<X: T1> for Sized?: T2 {}
+trait T4<Sized? X> {}
+trait T5<Sized? X, Y> {}
+trait T6<Y, Sized? X> {}
+trait T7<Sized? X, Sized? Y> {}
+trait T8<Sized? X: T2> {}
+struct S1<Sized? X>;
+enum E<Sized? X> {}
+impl <Sized? X> T1 for S1<X> {}
+fn f<Sized? X>() {}
pub fn main() {
}
// Test sized-ness checking in substitution.
// Unbounded.
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
f1::<X>(x);
}
fn f2<X>(x: &X) {
}
// Bounded.
-trait T for type {}
-fn f3<type X: T>(x: &X) {
+trait T for Sized? {}
+fn f3<Sized? X: T>(x: &X) {
f3::<X>(x);
}
fn f4<X: T>(x: &X) {
}
// Self type.
-trait T2 for type {
+trait T2 for Sized? {
fn f() -> Box<Self>;
}
struct S;
box S
}
}
-fn f5<type X: T2>(x: &X) {
+fn f5<Sized? X: T2>(x: &X) {
let _: Box<X> = T2::f();
}
fn f6<X: T2>(x: &X) {
let _: Box<X> = T2::f();
}
-trait T3 for type {
+trait T3 for Sized? {
fn f() -> Box<Self>;
}
impl T3 for S {
box S
}
}
-fn f7<type X: T3>(x: &X) {
+fn f7<Sized? X: T3>(x: &X) {
// This is valid, but the unsized bound on X is irrelevant because any type
// which implements T3 must have statically known size.
let _: Box<X> = T3::f();
fn m1(x: &T4<X>);
fn m2(x: &T5<X>);
}
-trait T5<type X> {
+trait T5<Sized? X> {
// not an error (for now)
fn m1(x: &T4<X>);
fn m2(x: &T5<X>);
fn m1(x: &T4<X>);
fn m2(x: &T5<X>);
}
-trait T7<type X: T> {
+trait T7<Sized? X: T> {
// not an error (for now)
fn m1(x: &T4<X>);
fn m2(x: &T5<X>);
}
// The last field in a struct or variant may be unsized
-struct S2<type X> {
+struct S2<Sized? X> {
f: X,
}
-struct S3<type X> {
+struct S3<Sized? X> {
f1: int,
f2: X,
}
-enum E<type X> {
+enum E<Sized? X> {
V1(X),
V2{x: X},
V3(int, X),