Skip to content

Commit dd7cde6

Browse files
author
Alexander Regueiro
committed
Extended elaboration for trait aliases to include arbitrary bounds.
1 parent 855a78e commit dd7cde6

File tree

6 files changed

+42
-26
lines changed

6 files changed

+42
-26
lines changed

src/librustc/traits/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ impl<I> FilterToTraits<I> {
333333
}
334334
}
335335

336-
impl<'tcx,I:Iterator<Item=ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
336+
impl<'tcx,I:Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
337337
type Item = ty::PolyTraitRef<'tcx>;
338338

339339
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {

src/librustc/ty/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,24 +1051,24 @@ pub enum Predicate<'tcx> {
10511051
/// would be the type parameters.
10521052
Trait(PolyTraitPredicate<'tcx>),
10531053

1054-
/// where 'a : 'b
1054+
/// where `'a : 'b`
10551055
RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
10561056

1057-
/// where T : 'a
1057+
/// where `T : 'a`
10581058
TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
10591059

1060-
/// where <T as TraitRef>::Name == X, approximately.
1061-
/// See `ProjectionPredicate` struct for details.
1060+
/// where `<T as TraitRef>::Name == X`, approximately.
1061+
/// See the `ProjectionPredicate` struct for details.
10621062
Projection(PolyProjectionPredicate<'tcx>),
10631063

1064-
/// no syntax: T WF
1064+
/// no syntax: `T` well-formed
10651065
WellFormed(Ty<'tcx>),
10661066

10671067
/// trait must be object-safe
10681068
ObjectSafe(DefId),
10691069

10701070
/// No direct syntax. May be thought of as `where T : FnFoo<...>`
1071-
/// for some substitutions `...` and T being a closure type.
1071+
/// for some substitutions `...` and `T` being a closure type.
10721072
/// Satisfied (or refuted) once we know the closure's kind.
10731073
ClosureKind(DefId, ClosureSubsts<'tcx>, ClosureKind),
10741074

src/librustc/ty/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
527527
self.def_key(def_id).disambiguated_data.data == DefPathData::ClosureExpr
528528
}
529529

530-
/// True if `def_id` refers to a trait (e.g., `trait Foo { ... }`).
530+
/// True if `def_id` refers to a trait (i.e., `trait Foo { ... }`).
531531
pub fn is_trait(self, def_id: DefId) -> bool {
532532
if let DefPathData::Trait(_) = self.def_key(def_id).disambiguated_data.data {
533533
true

src/librustc_typeck/astconv.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
544544
}
545545

546546
/// Given the type/region arguments provided to some path (along with
547-
/// an implicit Self, if this is a trait reference) returns the complete
547+
/// an implicit `Self`, if this is a trait reference) returns the complete
548548
/// set of substitutions. This may involve applying defaulted type parameters.
549549
///
550550
/// Note that the type listing given here is *exactly* what the user provided.
@@ -721,7 +721,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
721721
{
722722
let trait_def_id = self.trait_def_id(trait_ref);
723723

724-
debug!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
724+
debug!("instantiate_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
725725

726726
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
727727

@@ -738,11 +738,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
738738
let predicate: Result<_, ErrorReported> =
739739
self.ast_type_binding_to_poly_projection_predicate(
740740
trait_ref.ref_id, poly_trait_ref, binding, speculative, &mut dup_bindings);
741-
// ok to ignore Err() because ErrorReported (see above)
741+
// ok to ignore Err because ErrorReported (see above)
742742
Some((predicate.ok()?, binding.span))
743743
}));
744744

745-
debug!("ast_path_to_poly_trait_ref({:?}, projections={:?}) -> {:?}",
745+
debug!("instantiate_poly_trait_ref({:?}, projections={:?}) -> {:?}",
746746
trait_ref, poly_projections, poly_trait_ref);
747747
poly_trait_ref
748748
}
@@ -1020,7 +1020,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
10201020
return tcx.types.err;
10211021
}
10221022

1023-
// use a btreeset to keep output in a more consistent order
1023+
// use a BTreeSet to keep output in a more consistent order
10241024
let mut associated_types = BTreeSet::default();
10251025

10261026
for tr in traits::supertraits(tcx, principal) {

src/librustc_typeck/collect.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ fn type_param_predicates<'a, 'tcx>(
245245
use rustc::hir::*;
246246

247247
// In the AST, bounds can derive from two places. Either
248-
// written inline like `<T:Foo>` or in a where clause like
249-
// `where T:Foo`.
248+
// written inline like `<T : Foo>` or in a where clause like
249+
// `where T : Foo`.
250250

251251
let param_id = tcx.hir.as_local_node_id(def_id).unwrap();
252252
let param_owner = tcx.hir.ty_param_owner(param_id);
@@ -317,12 +317,12 @@ fn type_param_predicates<'a, 'tcx>(
317317
let icx = ItemCtxt::new(tcx, item_def_id);
318318
result
319319
.predicates
320-
.extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty));
320+
.extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, true));
321321
result
322322
}
323323

324324
impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
325-
/// Find bounds from hir::Generics. This requires scanning through the
325+
/// Find bounds from `hir::Generics`. This requires scanning through the
326326
/// AST. We do this to avoid having to convert *all* the bounds, which
327327
/// would create artificial cycles. Instead we can only convert the
328328
/// bounds for a type parameter `X` if `X::Foo` is used.
@@ -331,6 +331,7 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
331331
ast_generics: &hir::Generics,
332332
param_id: ast::NodeId,
333333
ty: Ty<'tcx>,
334+
only_self_bounds: bool,
334335
) -> Vec<(ty::Predicate<'tcx>, Span)> {
335336
let from_ty_params = ast_generics
336337
.params
@@ -350,9 +351,21 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
350351
hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
351352
_ => None,
352353
})
353-
.filter(|bp| is_param(self.tcx, &bp.bounded_ty, param_id))
354-
.flat_map(|bp| bp.bounds.iter())
355-
.flat_map(|b| predicates_from_bound(self, ty, b));
354+
.flat_map(|bp| {
355+
let bt = if is_param(self.tcx, &bp.bounded_ty, param_id) {
356+
Some(ty)
357+
} else {
358+
if only_self_bounds {
359+
None
360+
} else {
361+
Some(self.to_ty(&bp.bounded_ty))
362+
}
363+
};
364+
bp.bounds.iter().filter_map(move |b| {
365+
if let Some(bt) = bt { Some((bt, b)) } else { None }
366+
})
367+
})
368+
.flat_map(|(bt, b)| predicates_from_bound(self, bt, b));
356369

357370
from_ty_params.chain(from_where_clauses).collect()
358371
}
@@ -690,22 +703,25 @@ fn super_predicates_of<'a, 'tcx>(
690703

691704
let icx = ItemCtxt::new(tcx, trait_def_id);
692705

693-
// Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
706+
// Convert the bounds that follow the colon, e.g. `Bar + Zed` in `trait Foo : Bar + Zed`.
694707
let self_param_ty = tcx.mk_self_type();
695708
let superbounds1 = compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span);
696709

697710
let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
698711

699712
// Convert any explicit superbounds in the where clause,
700713
// e.g. `trait Foo where Self : Bar`:
701-
let superbounds2 = icx.type_parameter_bounds_in_generics(generics, item.id, self_param_ty);
714+
let is_trait_alias = ty::is_trait_alias(tcx, trait_def_id);
715+
let superbounds2 = icx.type_parameter_bounds_in_generics(
716+
generics, item.id, self_param_ty, !is_trait_alias);
702717

703718
// Combine the two lists to form the complete set of superbounds:
704719
let superbounds: Vec<_> = superbounds1.into_iter().chain(superbounds2).collect();
705720

706721
// Now require that immediate supertraits are converted,
707722
// which will, in turn, reach indirect supertraits.
708723
for &(pred, span) in &superbounds {
724+
debug!("superbound: {:?}", pred);
709725
if let ty::Predicate::Trait(bound) = pred {
710726
tcx.at(span).super_predicates_of(bound.def_id());
711727
}
@@ -2007,10 +2023,10 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
20072023
}
20082024
}
20092025

2010-
/// Converts a specific GenericBound from the AST into a set of
2026+
/// Converts a specific `GenericBound` from the AST into a set of
20112027
/// predicates that apply to the self-type. A vector is returned
2012-
/// because this can be anywhere from 0 predicates (`T:?Sized` adds no
2013-
/// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
2028+
/// because this can be anywhere from zero predicates (`T : ?Sized` adds no
2029+
/// predicates) to one (`T : Foo`) to many (`T : Bar<X=i32>` adds `T : Bar`
20142030
/// and `<T as Bar>::X == i32`).
20152031
fn predicates_from_bound<'tcx>(
20162032
astconv: &dyn AstConv<'tcx, 'tcx>,

src/test/ui/traits/trait-alias-fail1.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ LL | trait BoundedAlias<T: Clone = ()> = Default;
3535
error[E0658]: trait aliases are experimental (see issue #41517)
3636
--> $DIR/trait-alias-fail1.rs:17:1
3737
|
38-
LL | trait B<T> = A<T>; // FIXME: this should not work... or should it?
38+
LL | trait B<T> = A<T>; // FIXME: parameter T should need a bound here, or semantics should be changed
3939
| ^^^^^^^^^^^^^^^^^^
4040
|
4141
= help: add #![feature(trait_alias)] to the crate attributes to enable

0 commit comments

Comments
 (0)