Skip to content

Commit e656081

Browse files
committed
Accept ?Sized as well as Sized?
Includes a bit of refactoring to store `?` unbounds as bounds with a modifier, rather than in their own world, in the AST at least.
1 parent 5ba6102 commit e656081

File tree

26 files changed

+179
-138
lines changed

26 files changed

+179
-138
lines changed

src/librustc/lint/builtin.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,9 +1782,9 @@ impl LintPass for Stability {
17821782
if self.is_internal(cx, item.span) { return }
17831783

17841784
match item.node {
1785-
ast::ItemTrait(_, _, _, ref supertraits, _) => {
1785+
ast::ItemTrait(_, _, ref supertraits, _) => {
17861786
for t in supertraits.iter() {
1787-
if let ast::TraitTyParamBound(ref t) = *t {
1787+
if let ast::TraitTyParamBound(ref t, _) = *t {
17881788
let id = ty::trait_ref_to_def_id(cx.tcx, &t.trait_ref);
17891789
self.lint(cx, id, t.trait_ref.path.span);
17901790
}

src/librustc/metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
13081308
}
13091309
}
13101310
}
1311-
ast::ItemTrait(_, _, _, _, ref ms) => {
1311+
ast::ItemTrait(_, _, _, ref ms) => {
13121312
add_to_index(item, rbml_w, index);
13131313
rbml_w.start_tag(tag_items_data_item);
13141314
encode_def_id(rbml_w, def_id);

src/librustc/middle/infer/error_reporting.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,6 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
10431043
ident: ty_param.ident,
10441044
id: ty_param.id,
10451045
bounds: bounds,
1046-
unbound: ty_param.unbound.clone(),
10471046
default: ty_param.default.clone(),
10481047
span: ty_param.span,
10491048
}
@@ -1063,7 +1062,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
10631062
// be passing down a map.
10641063
ast::RegionTyParamBound(lt)
10651064
}
1066-
&ast::TraitTyParamBound(ref poly_tr) => {
1065+
&ast::TraitTyParamBound(ref poly_tr, modifier) => {
10671066
let tr = &poly_tr.trait_ref;
10681067
let last_seg = tr.path.segments.last().unwrap();
10691068
let mut insert = Vec::new();
@@ -1087,7 +1086,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
10871086
path: new_path,
10881087
ref_id: tr.ref_id,
10891088
}
1090-
})
1089+
}, modifier)
10911090
}
10921091
}
10931092
})

src/librustc/middle/privacy.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl<'v> Visitor<'v> for ParentVisitor {
122122
// method to the root. In this case, if the trait is private, then
123123
// parent all the methods to the trait to indicate that they're
124124
// private.
125-
ast::ItemTrait(_, _, _, _, ref methods) if item.vis != ast::Public => {
125+
ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => {
126126
for m in methods.iter() {
127127
match *m {
128128
ast::ProvidedMethod(ref m) => {
@@ -328,7 +328,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
328328

329329
// Default methods on traits are all public so long as the trait
330330
// is public
331-
ast::ItemTrait(_, _, _, _, ref methods) if public_first => {
331+
ast::ItemTrait(_, _, _, ref methods) if public_first => {
332332
for method in methods.iter() {
333333
match *method {
334334
ast::ProvidedMethod(ref m) => {
@@ -1178,7 +1178,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
11781178
}
11791179
}
11801180

1181-
ast::ItemTrait(_, _, _, _, ref methods) => {
1181+
ast::ItemTrait(_, _, _, ref methods) => {
11821182
for m in methods.iter() {
11831183
match *m {
11841184
ast::ProvidedMethod(ref m) => {
@@ -1242,7 +1242,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
12421242

12431243
ast::ItemStruct(ref def, _) => check_struct(&**def),
12441244

1245-
ast::ItemTrait(_, _, _, _, ref methods) => {
1245+
ast::ItemTrait(_, _, _, ref methods) => {
12461246
for m in methods.iter() {
12471247
match *m {
12481248
ast::RequiredMethod(..) => {}
@@ -1306,7 +1306,7 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
13061306

13071307
fn check_ty_param_bound(&self,
13081308
ty_param_bound: &ast::TyParamBound) {
1309-
if let ast::TraitTyParamBound(ref trait_ref) = *ty_param_bound {
1309+
if let ast::TraitTyParamBound(ref trait_ref, _) = *ty_param_bound {
13101310
if !self.tcx.sess.features.borrow().visible_private_types &&
13111311
self.path_is_private_type(trait_ref.trait_ref.ref_id) {
13121312
let span = trait_ref.trait_ref.path.span;
@@ -1349,7 +1349,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
13491349
// namespace (the contents have their own privacies).
13501350
ast::ItemForeignMod(_) => {}
13511351

1352-
ast::ItemTrait(_, _, _, ref bounds, _) => {
1352+
ast::ItemTrait(_, _, ref bounds, _) => {
13531353
if !self.trait_is_public(item.id) {
13541354
return
13551355
}

src/librustc/middle/resolve_lifetime.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
105105
ast::ItemTy(_, ref generics) |
106106
ast::ItemEnum(_, ref generics) |
107107
ast::ItemStruct(_, ref generics) |
108-
ast::ItemTrait(_, ref generics, _, _, _) |
108+
ast::ItemTrait(_, ref generics, _, _) |
109109
ast::ItemImpl(_, ref generics, _, _, _) => {
110110
// These kinds of items have only early bound lifetime parameters.
111111
let lifetimes = &generics.lifetimes;
@@ -232,7 +232,9 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
232232
}
233233
}
234234

235-
fn visit_poly_trait_ref(&mut self, trait_ref: &ast::PolyTraitRef) {
235+
fn visit_poly_trait_ref(&mut self, trait_ref:
236+
&ast::PolyTraitRef,
237+
_modifier: &ast::TraitBoundModifier) {
236238
debug!("visit_poly_trait_ref trait_ref={}", trait_ref);
237239

238240
self.with(LateScope(&trait_ref.bound_lifetimes, self.scope), |old_scope, this| {

src/librustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4608,7 +4608,7 @@ pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
46084608
match cx.map.find(id.node) {
46094609
Some(ast_map::NodeItem(item)) => {
46104610
match item.node {
4611-
ItemTrait(_, _, _, _, ref ms) => {
4611+
ItemTrait(_, _, _, ref ms) => {
46124612
let (_, p) =
46134613
ast_util::split_trait_methods(ms[]);
46144614
p.iter()

src/librustc_resolve/lib.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,7 @@ impl<'a> Resolver<'a> {
14591459

14601460
ItemImpl(_, _, Some(_), _, _) => parent,
14611461

1462-
ItemTrait(_, _, _, _, ref items) => {
1462+
ItemTrait(_, _, _, ref items) => {
14631463
let name_bindings =
14641464
self.add_child(name,
14651465
parent.clone(),
@@ -3998,7 +3998,7 @@ impl<'a> Resolver<'a> {
39983998
impl_items[]);
39993999
}
40004000

4001-
ItemTrait(_, ref generics, ref unbound, ref bounds, ref trait_items) => {
4001+
ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
40024002
// Create a new rib for the self type.
40034003
let mut self_type_rib = Rib::new(ItemRibKind);
40044004

@@ -4019,13 +4019,6 @@ impl<'a> Resolver<'a> {
40194019
this.resolve_type_parameter_bounds(item.id, bounds,
40204020
TraitDerivation);
40214021

4022-
match *unbound {
4023-
Some(ref tpb) => {
4024-
this.resolve_trait_reference(item.id, tpb, TraitDerivation);
4025-
}
4026-
None => {}
4027-
}
4028-
40294022
for trait_item in (*trait_items).iter() {
40304023
// Create a new rib for the trait_item-specific type
40314024
// parameters.
@@ -4273,12 +4266,6 @@ impl<'a> Resolver<'a> {
42734266
self.resolve_type_parameter_bound(type_parameter.id, bound,
42744267
TraitBoundingTypeParameter);
42754268
}
4276-
match &type_parameter.unbound {
4277-
&Some(ref unbound) =>
4278-
self.resolve_trait_reference(
4279-
type_parameter.id, unbound, TraitBoundingTypeParameter),
4280-
&None => {}
4281-
}
42824269
match type_parameter.default {
42834270
Some(ref ty) => self.resolve_type(&**ty),
42844271
None => {}
@@ -4300,7 +4287,7 @@ impl<'a> Resolver<'a> {
43004287
type_parameter_bound: &TyParamBound,
43014288
reference_type: TraitReferenceType) {
43024289
match *type_parameter_bound {
4303-
TraitTyParamBound(ref tref) => {
4290+
TraitTyParamBound(ref tref, _) => {
43044291
self.resolve_poly_trait_reference(id, tref, reference_type)
43054292
}
43064293
RegionTyParamBound(..) => {}

src/librustc_trans/save/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
710710
// super-traits
711711
for super_bound in trait_refs.iter() {
712712
let trait_ref = match *super_bound {
713-
ast::TraitTyParamBound(ref trait_ref) => {
713+
ast::TraitTyParamBound(ref trait_ref, _) => {
714714
trait_ref
715715
}
716716
ast::RegionTyParamBound(..) => {
@@ -1052,7 +1052,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
10521052
&**typ,
10531053
impl_items)
10541054
}
1055-
ast::ItemTrait(_, ref generics, _, ref trait_refs, ref methods) =>
1055+
ast::ItemTrait(_, ref generics, ref trait_refs, ref methods) =>
10561056
self.process_trait(item, generics, trait_refs, methods),
10571057
ast::ItemMod(ref m) => self.process_mod(item, m),
10581058
ast::ItemTy(ref ty, ref ty_params) => {
@@ -1076,7 +1076,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
10761076
fn visit_generics(&mut self, generics: &ast::Generics) {
10771077
for param in generics.ty_params.iter() {
10781078
for bound in param.bounds.iter() {
1079-
if let ast::TraitTyParamBound(ref trait_ref) = *bound {
1079+
if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
10801080
self.process_trait_ref(&trait_ref.trait_ref, None);
10811081
}
10821082
}

src/librustc_typeck/astconv.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
16251625
let mut trait_def_ids = DefIdMap::new();
16261626
for ast_bound in ast_bounds.iter() {
16271627
match *ast_bound {
1628-
ast::TraitTyParamBound(ref b) => {
1628+
ast::TraitTyParamBound(ref b, ast::TraitBoundModifier::None) => {
16291629
match ::lookup_def_tcx(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
16301630
def::DefTrait(trait_did) => {
16311631
match trait_def_ids.get(&trait_did) {
@@ -1663,6 +1663,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
16631663
}
16641664
trait_bounds.push(b);
16651665
}
1666+
ast::TraitTyParamBound(_, ast::TraitBoundModifier::Maybe) => {}
16661667
ast::RegionTyParamBound(ref l) => {
16671668
region_bounds.push(l);
16681669
}

src/librustc_typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
658658
}
659659

660660
}
661-
ast::ItemTrait(_, _, _, _, ref trait_methods) => {
661+
ast::ItemTrait(_, _, _, ref trait_methods) => {
662662
let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
663663
for trait_method in trait_methods.iter() {
664664
match *trait_method {

src/librustc_typeck/collect.rs

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
259259
trait_def: &ty::TraitDef<'tcx>) {
260260
let tcx = ccx.tcx;
261261
if let ast_map::NodeItem(item) = tcx.map.get(trait_id) {
262-
if let ast::ItemTrait(_, _, _, _, ref trait_items) = item.node {
262+
if let ast::ItemTrait(_, _, _, ref trait_items) = item.node {
263263
// For each method, construct a suitable ty::Method and
264264
// store it into the `tcx.impl_or_trait_items` table:
265265
for trait_item in trait_items.iter() {
@@ -627,11 +627,6 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
627627
ast::RegionTyParamBound(..) => { }
628628
}
629629
}
630-
631-
match ty_param.unbound {
632-
Some(_) => { warn = true; }
633-
None => { }
634-
}
635630
}
636631

637632
if warn {
@@ -1146,7 +1141,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
11461141
AllowEqConstraints::DontAllow);
11471142
}
11481143
},
1149-
ast::ItemTrait(_, _, _, _, ref trait_methods) => {
1144+
ast::ItemTrait(_, _, _, ref trait_methods) => {
11501145
let trait_def = trait_def_of_item(ccx, it);
11511146

11521147
debug!("trait_def: ident={} trait_def={}",
@@ -1338,13 +1333,12 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
13381333
return def.clone();
13391334
}
13401335

1341-
let (unsafety, generics, unbound, bounds, items) = match it.node {
1336+
let (unsafety, generics, bounds, items) = match it.node {
13421337
ast::ItemTrait(unsafety,
13431338
ref generics,
1344-
ref unbound,
13451339
ref supertraits,
13461340
ref items) => {
1347-
(unsafety, generics, unbound, supertraits, items.as_slice())
1341+
(unsafety, generics, supertraits, items.as_slice())
13481342
}
13491343
ref s => {
13501344
tcx.sess.span_bug(
@@ -1367,7 +1361,6 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
13671361
token::SELF_KEYWORD_NAME,
13681362
self_param_ty,
13691363
bounds.as_slice(),
1370-
unbound,
13711364
it.span);
13721365

13731366
let substs = mk_item_substs(ccx, &ty_generics);
@@ -1683,29 +1676,37 @@ fn ty_generics_for_fn_or_method<'tcx,AC>(
16831676
create_type_parameters_for_associated_types)
16841677
}
16851678

1686-
// Add the Sized bound, unless the type parameter is marked as `Sized?`.
1679+
// Add the Sized bound, unless the type parameter is marked as `?Sized`.
16871680
fn add_unsized_bound<'tcx,AC>(this: &AC,
1688-
unbound: &Option<ast::TraitRef>,
16891681
bounds: &mut ty::BuiltinBounds,
1690-
desc: &str,
1682+
ast_bounds: &[ast::TyParamBound],
16911683
span: Span)
16921684
where AC: AstConv<'tcx> {
1685+
// Try to find an unbound in bounds.
1686+
let mut unbound = None;
1687+
for ab in ast_bounds.iter() {
1688+
if let &ast::TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = ab {
1689+
if unbound.is_none() {
1690+
assert!(ptr.bound_lifetimes.is_empty());
1691+
unbound = Some(ptr.trait_ref.clone());
1692+
} else {
1693+
this.tcx().sess.span_err(span, "type parameter has more than one relaxed default \
1694+
bound, only one is supported");
1695+
}
1696+
}
1697+
}
1698+
16931699
let kind_id = this.tcx().lang_items.require(SizedTraitLangItem);
16941700
match unbound {
1695-
&Some(ref tpb) => {
1701+
Some(ref tpb) => {
16961702
// FIXME(#8559) currently requires the unbound to be built-in.
16971703
let trait_def_id = ty::trait_ref_to_def_id(this.tcx(), tpb);
16981704
match kind_id {
16991705
Ok(kind_id) if trait_def_id != kind_id => {
17001706
this.tcx().sess.span_warn(span,
1701-
format!("default bound relaxed \
1702-
for a {}, but this \
1703-
does nothing because \
1704-
the given bound is not \
1705-
a default. \
1706-
Only `Sized?` is \
1707-
supported",
1708-
desc)[]);
1707+
"default bound relaxed for a type parameter, but \
1708+
this does nothing because the given bound is not \
1709+
a default. Only `?Sized` is supported");
17091710
ty::try_add_builtin_trait(this.tcx(),
17101711
kind_id,
17111712
bounds);
@@ -1717,7 +1718,7 @@ fn add_unsized_bound<'tcx,AC>(this: &AC,
17171718
ty::try_add_builtin_trait(this.tcx(), kind_id.unwrap(), bounds);
17181719
}
17191720
// No lang item for Sized, so we can't add it as a bound.
1720-
&None => {}
1721+
None => {}
17211722
}
17221723
}
17231724

@@ -1807,7 +1808,7 @@ fn ty_generics<'tcx,AC>(this: &AC,
18071808

18081809
for bound in bound_pred.bounds.iter() {
18091810
match bound {
1810-
&ast::TyParamBound::TraitTyParamBound(ref poly_trait_ref) => {
1811+
&ast::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
18111812
let trait_ref = astconv::instantiate_poly_trait_ref(
18121813
this,
18131814
&ExplicitRscope,
@@ -1880,7 +1881,7 @@ fn ty_generics<'tcx,AC>(this: &AC,
18801881
for bound in param.bounds.iter() {
18811882
// In the above example, `ast_trait_ref` is `Iterator`.
18821883
let ast_trait_ref = match *bound {
1883-
ast::TraitTyParamBound(ref r) => r,
1884+
ast::TraitTyParamBound(ref r, _) => r,
18841885
ast::RegionTyParamBound(..) => { continue; }
18851886
};
18861887

@@ -1978,7 +1979,6 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
19781979
param.ident.name,
19791980
param_ty,
19801981
param.bounds[],
1981-
&param.unbound,
19821982
param.span);
19831983
let default = match param.default {
19841984
None => None,
@@ -2023,7 +2023,6 @@ fn compute_bounds<'tcx,AC>(this: &AC,
20232023
name_of_bounded_thing: ast::Name,
20242024
param_ty: ty::ParamTy,
20252025
ast_bounds: &[ast::TyParamBound],
2026-
unbound: &Option<ast::TraitRef>,
20272026
span: Span)
20282027
-> ty::ParamBounds<'tcx>
20292028
where AC: AstConv<'tcx> {
@@ -2032,11 +2031,9 @@ fn compute_bounds<'tcx,AC>(this: &AC,
20322031
param_ty,
20332032
ast_bounds);
20342033

2035-
20362034
add_unsized_bound(this,
2037-
unbound,
20382035
&mut param_bounds.builtin_bounds,
2039-
"type parameter",
2036+
ast_bounds,
20402037
span);
20412038

20422039
check_bounds_compatible(this.tcx(),

0 commit comments

Comments
 (0)