Skip to content

Commit 1c92ba7

Browse files
author
Alexander Regueiro
committed
Added support for trait aliases as object types.
1 parent 58a1b5a commit 1c92ba7

File tree

7 files changed

+43
-34
lines changed

7 files changed

+43
-34
lines changed

src/librustc/hir/lowering.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4875,23 +4875,24 @@ impl<'a> LoweringContext<'a> {
48754875
let node = match qpath {
48764876
hir::QPath::Resolved(None, path) => {
48774877
// Turn trait object paths into `TyKind::TraitObject` instead.
4878-
if let Def::Trait(_) = path.def {
4879-
let principal = hir::PolyTraitRef {
4880-
bound_generic_params: hir::HirVec::new(),
4881-
trait_ref: hir::TraitRef {
4882-
path: path.and_then(|path| path),
4883-
ref_id: id.node_id,
4884-
hir_ref_id: id.hir_id,
4885-
},
4886-
span,
4887-
};
4878+
match path.def {
4879+
Def::Trait(_) | Def::TraitAlias(_) => {
4880+
let principal = hir::PolyTraitRef {
4881+
bound_generic_params: hir::HirVec::new(),
4882+
trait_ref: hir::TraitRef {
4883+
path: path.and_then(|path| path),
4884+
ref_id: id.node_id,
4885+
hir_ref_id: id.hir_id,
4886+
},
4887+
span,
4888+
};
48884889

4889-
// The original ID is taken by the `PolyTraitRef`,
4890-
// so the `Ty` itself needs a different one.
4891-
id = self.next_id();
4892-
hir::TyKind::TraitObject(hir_vec![principal], self.elided_dyn_bound(span))
4893-
} else {
4894-
hir::TyKind::Path(hir::QPath::Resolved(None, path))
4890+
// The original ID is taken by the `PolyTraitRef`,
4891+
// so the `Ty` itself needs a different one.
4892+
id = self.next_id();
4893+
hir::TyKind::TraitObject(hir_vec![principal], self.elided_dyn_bound(span))
4894+
}
4895+
_ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
48954896
}
48964897
}
48974898
_ => hir::TyKind::Path(qpath),

src/librustc_resolve/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -538,9 +538,9 @@ impl<'a> PathSource<'a> {
538538
match self {
539539
PathSource::Type => match def {
540540
Def::Struct(..) | Def::Union(..) | Def::Enum(..) |
541-
Def::Trait(..) | Def::TyAlias(..) | Def::AssociatedTy(..) |
542-
Def::PrimTy(..) | Def::TyParam(..) | Def::SelfTy(..) |
543-
Def::Existential(..) |
541+
Def::Trait(..) | Def::TraitAlias(..) | Def::TyAlias(..) |
542+
Def::AssociatedTy(..) | Def::PrimTy(..) | Def::TyParam(..) |
543+
Def::SelfTy(..) | Def::Existential(..) |
544544
Def::ForeignTy(..) => true,
545545
_ => false,
546546
},
@@ -3122,7 +3122,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
31223122
return (err, candidates);
31233123
}
31243124
(Def::TyAlias(..), PathSource::Trait(_)) => {
3125-
err.span_label(span, "type aliases cannot be used for traits");
3125+
err.span_label(span, "type aliases cannot be used as traits");
3126+
if nightly_options::is_nightly_build() {
3127+
err.note("did you mean to use a trait alias?");
3128+
}
31263129
return (err, candidates);
31273130
}
31283131
(Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {

src/librustc_typeck/astconv.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! Conversion from AST representation of types to the ty.rs
11+
//! Conversion from AST representation of types to the `ty.rs`
1212
//! representation. The main routine here is `ast_ty_to_ty()`: each use
1313
//! is parameterized by an instance of `AstConv`.
1414
@@ -181,7 +181,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
181181
item_segment: &hir::PathSegment)
182182
-> &'tcx Substs<'tcx>
183183
{
184-
185184
let (substs, assoc_bindings) = item_segment.with_generic_args(|generic_args| {
186185
self.create_substs_for_ast_path(
187186
span,
@@ -948,8 +947,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
948947
)
949948
}
950949

951-
/// Transform a PolyTraitRef into a PolyExistentialTraitRef by
952-
/// removing the dummy Self type (TRAIT_OBJECT_DUMMY_SELF).
950+
/// Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by
951+
/// removing the dummy `Self` type (`TRAIT_OBJECT_DUMMY_SELF`).
953952
fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
954953
-> ty::ExistentialTraitRef<'tcx> {
955954
assert_eq!(trait_ref.self_ty().sty, TRAIT_OBJECT_DUMMY_SELF);
@@ -1347,7 +1346,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
13471346
err.span_label(span, "associated type not allowed here").emit();
13481347
}
13491348

1350-
// Check a type Path and convert it to a Ty.
1349+
// Check a type `Path` and convert it to a `Ty`.
13511350
pub fn def_to_ty(&self,
13521351
opt_self_ty: Option<Ty<'tcx>>,
13531352
path: &hir::Path,
@@ -1442,8 +1441,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
14421441
/// Parses the programmer's textual representation of a type into our
14431442
/// internal notion of a type.
14441443
pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
1445-
debug!("ast_ty_to_ty(id={:?}, ast_ty={:?})",
1446-
ast_ty.id, ast_ty);
1444+
debug!("ast_ty_to_ty(id={:?}, ast_ty={:?} ty_ty={:?})",
1445+
ast_ty.id, ast_ty, ast_ty.node);
14471446

14481447
let tcx = self.tcx();
14491448

src/libsyntax/ast.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,9 @@ pub enum TraitBoundModifier {
288288
}
289289

290290
/// The AST represents all type param bounds as types.
291-
/// typeck::collect::compute_bounds matches these against
292-
/// the "special" built-in traits (see middle::lang_items) and
293-
/// detects Copy, Send and Sync.
291+
/// `typeck::collect::compute_bounds` matches these against
292+
/// the "special" built-in traits (see `middle::lang_items`) and
293+
/// detects `Copy`, `Send` and `Sync`.
294294
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
295295
pub enum GenericBound {
296296
Trait(PolyTraitRef, TraitBoundModifier),

src/libsyntax/ext/expand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ impl Invocation {
252252

253253
pub struct MacroExpander<'a, 'b:'a> {
254254
pub cx: &'a mut ExtCtxt<'b>,
255-
monotonic: bool, // c.f. `cx.monotonic_expander()`
255+
monotonic: bool, // cf. `cx.monotonic_expander()`
256256
}
257257

258258
impl<'a, 'b> MacroExpander<'a, 'b> {

src/libsyntax/parse/parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,7 @@ impl<'a> Parser<'a> {
15321532
if maybe_bounds && bounds.len() == 1 && !trailing_plus => {
15331533
let path = match bounds[0] {
15341534
GenericBound::Trait(ref pt, ..) => pt.trait_ref.path.clone(),
1535-
_ => self.bug("unexpected lifetime bound"),
1535+
GenericBound::Outlives(..) => self.bug("unexpected lifetime bound"),
15361536
};
15371537
self.parse_remaining_bounds(Vec::new(), path, lo, true)?
15381538
}

src/test/run-pass/traits/trait-alias.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@
1010

1111
#![feature(trait_alias)]
1212

13-
trait Foo = std::fmt::Debug;
13+
type Foo = std::fmt::Debug;
14+
type Bar = Foo;
1415

1516
fn foo<T: Foo>(v: &T) {
1617
println!("{:?}", v);
1718
}
1819

1920
pub fn main() {
2021
foo(&12345);
21-
let foo: &Foo = &0i32;
22+
23+
let bar1: &Bar = &54321;
24+
println!("{:?}", bar1);
25+
26+
let bar2 = Box::new(42) as Box<dyn Foo>;
27+
println!("{:?}", bar2);
2228
}

0 commit comments

Comments
 (0)