Change DST syntax: type -> Sized?
closes #13367 [breaking-change] Use `Sized?` to indicate a dynamically sized type parameter or trait (used to be `type`). E.g., ``` trait Tr for Sized? {} fn foo<Sized? X: Share>(x: X) {} ```
This commit is contained in:
parent
6959931498
commit
a0cfda53c4
29 changed files with 215 additions and 178 deletions
|
|
@ -109,12 +109,12 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
|
|||
.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())
|
||||
|
|
|
|||
|
|
@ -164,19 +164,6 @@ fn item_visibility(item: ebml::Doc) -> ast::Visibility {
|
|||
}
|
||||
}
|
||||
|
||||
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| {
|
||||
|
|
@ -393,7 +380,6 @@ pub fn get_trait_def(cdata: Cmd,
|
|||
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.
|
||||
|
|
@ -405,12 +391,6 @@ pub fn get_trait_def(cdata: Cmd,
|
|||
});
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -881,16 +881,6 @@ fn encode_extension_implementations(ecx: &EncodeContext,
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
@ -1149,7 +1139,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
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);
|
||||
|
|
@ -1163,9 +1153,6 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
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() {
|
||||
|
|
|
|||
|
|
@ -3598,6 +3598,7 @@ impl<'a> Resolver<'a> {
|
|||
item.id,
|
||||
ItemRibKind),
|
||||
|this| {
|
||||
this.resolve_type_parameters(&generics.ty_params);
|
||||
visit::walk_item(this, item, ());
|
||||
});
|
||||
}
|
||||
|
|
@ -3623,7 +3624,7 @@ impl<'a> Resolver<'a> {
|
|||
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);
|
||||
|
||||
|
|
@ -3645,6 +3646,12 @@ impl<'a> Resolver<'a> {
|
|||
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
|
||||
|
|
@ -3856,11 +3863,15 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
|
||||
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 => {}
|
||||
|
|
@ -3887,9 +3898,9 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -692,9 +692,9 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
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(
|
||||
|
|
@ -711,7 +711,7 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
|
|||
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 {
|
||||
|
|
@ -759,7 +759,7 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<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;
|
||||
|
|
@ -798,15 +798,7 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -974,6 +966,43 @@ fn ty_generics_for_fn_or_method(ccx: &CrateCtxt,
|
|||
&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>,
|
||||
|
|
@ -1016,7 +1045,7 @@ fn ty_generics(ccx: &CrateCtxt,
|
|||
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| {
|
||||
|
|
@ -1056,7 +1085,7 @@ fn ty_generics(ccx: &CrateCtxt,
|
|||
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
|
||||
{
|
||||
|
|
@ -1113,15 +1142,11 @@ fn ty_generics(ccx: &CrateCtxt,
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -895,9 +895,9 @@ impl<'a> Rebuilder<'a> {
|
|||
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,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue