提交 41553d6f 编写于 作者: E Eduard-Mihai Burtescu

rustc: lower trait type paths as TyTraitObject.

上级 9783947c
......@@ -337,7 +337,8 @@ fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
return self.lower_ty(ty);
}
TyKind::Path(ref qself, ref path) => {
hir::TyPath(self.lower_qpath(t.id, qself, path, ParamMode::Explicit))
let qpath = self.lower_qpath(t.id, qself, path, ParamMode::Explicit);
return self.ty_path(t.id, t.span, qpath);
}
TyKind::ImplicitSelf => {
hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
......@@ -470,7 +471,8 @@ fn lower_qpath(&mut self,
// Otherwise, the base path is an implicit `Self` type path,
// e.g. `Vec` in `Vec::new` or `<I as Iterator>::Item` in
// `<I as Iterator>::Item::default`.
self.ty(p.span, hir::TyPath(hir::QPath::Resolved(qself, path)))
let new_id = self.next_id();
self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path))
};
// Anything after the base path are associated "extensions",
......@@ -493,7 +495,8 @@ fn lower_qpath(&mut self,
}
// Wrap the associated extension in another type node.
ty = self.ty(p.span, hir::TyPath(qpath));
let new_id = self.next_id();
ty = self.ty_path(new_id, p.span, qpath);
}
// Should've returned in the for loop above.
......@@ -2352,12 +2355,33 @@ fn signal_block_expr(&mut self,
self.expr_block(block, attrs)
}
fn ty(&mut self, span: Span, node: hir::Ty_) -> P<hir::Ty> {
P(hir::Ty {
id: self.next_id(),
node: node,
span: span,
})
fn ty_path(&mut self, id: NodeId, span: Span, qpath: hir::QPath) -> P<hir::Ty> {
let mut id = id;
let node = match qpath {
hir::QPath::Resolved(None, path) => {
// Turn trait object paths into `TyTraitObject` instead.
if let Def::Trait(_) = path.def {
let principal = hir::TraitTyParamBound(hir::PolyTraitRef {
bound_lifetimes: hir_vec![],
trait_ref: hir::TraitRef {
path: path.and_then(|path| path),
ref_id: id,
},
span,
}, hir::TraitBoundModifier::None);
// The original ID is taken by the `PolyTraitRef`,
// so the `Ty` itself needs a different one.
id = self.next_id();
hir::TyTraitObject(hir_vec![principal])
} else {
hir::TyPath(hir::QPath::Resolved(None, path))
}
}
_ => hir::TyPath(qpath)
};
P(hir::Ty { id, node, span })
}
fn elided_lifetime(&mut self, span: Span) -> hir::Lifetime {
......
......@@ -29,6 +29,7 @@
#![feature(conservative_impl_trait)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(field_init_shorthand)]
#![feature(libc)]
#![feature(loop_break_value)]
#![feature(nonzero)]
......
......@@ -322,24 +322,6 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
intravisit::walk_ty(this, ty);
});
}
hir::TyPath(hir::QPath::Resolved(None, ref path)) => {
// if this path references a trait, then this will resolve to
// a trait ref, which introduces a binding scope.
match path.def {
Def::Trait(..) => {
let scope = Scope::Binder {
lifetimes: FxHashMap(),
s: self.scope
};
self.with(scope, |_, this| {
this.visit_path(path, ty.id);
});
}
_ => {
intravisit::walk_ty(self, ty);
}
}
}
_ => {
intravisit::walk_ty(self, ty)
}
......@@ -889,7 +871,6 @@ fn visit_fn_like_elision(&mut self, inputs: &'tcx [P<hir::Ty>],
Def::Struct(_) |
Def::Union(_) |
Def::Enum(_) |
Def::Trait(_) |
Def::PrimTy(_) => return def == path.def,
_ => {}
}
......@@ -970,21 +951,13 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
}
fn visit_ty(&mut self, ty: &hir::Ty) {
let delta = match ty.node {
hir::TyBareFn(_) => 1,
hir::TyPath(hir::QPath::Resolved(None, ref path)) => {
// if this path references a trait, then this will resolve to
// a trait ref, which introduces a binding scope.
match path.def {
Def::Trait(..) => 1,
_ => 0
}
if let hir::TyBareFn(_) = ty.node {
self.binder_depth += 1;
}
_ => 0
};
self.binder_depth += delta;
intravisit::walk_ty(self, ty);
self.binder_depth -= delta;
if let hir::TyBareFn(_) = ty.node {
self.binder_depth -= 1;
}
}
fn visit_poly_trait_ref(&mut self,
......
......@@ -1151,7 +1151,6 @@ pub fn def_to_ty(&self,
rscope: &RegionScope,
opt_self_ty: Option<Ty<'tcx>>,
path: &hir::Path,
path_id: ast::NodeId,
permit_variants: bool)
-> Ty<'tcx> {
let tcx = self.tcx();
......@@ -1161,21 +1160,6 @@ pub fn def_to_ty(&self,
let span = path.span;
match path.def {
Def::Trait(trait_def_id) => {
// N.B. this case overlaps somewhat with
// TyTraitObject, see that fn for details
assert_eq!(opt_self_ty, None);
tcx.prohibit_type_params(path.segments.split_last().unwrap().1);
self.trait_path_to_object_type(rscope,
span,
trait_def_id,
path_id,
path.segments.last().unwrap(),
span,
partition_bounds(&[]))
}
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => {
assert_eq!(opt_self_ty, None);
tcx.prohibit_type_params(path.segments.split_last().unwrap().1);
......@@ -1421,7 +1405,7 @@ pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> {
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
self.ast_ty_to_ty(rscope, qself)
});
self.def_to_ty(rscope, opt_self_ty, path, ast_ty.id, false)
self.def_to_ty(rscope, opt_self_ty, path, false)
}
hir::TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => {
debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment);
......
......@@ -3976,7 +3976,7 @@ fn finish_resolving_struct_path(&self,
match *qpath {
hir::QPath::Resolved(ref maybe_qself, ref path) => {
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
let ty = AstConv::def_to_ty(self, self, opt_self_ty, path, node_id, true);
let ty = AstConv::def_to_ty(self, self, opt_self_ty, path, true);
(path.def, ty)
}
hir::QPath::TypeRelative(ref qself, ref segment) => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册