rustc: lower trait type paths as TyTraitObject.
This commit is contained in:
parent
9783947c2a
commit
41553d6fbc
@ -337,7 +337,8 @@ impl<'a> LoweringContext<'a> {
|
|||||||
return self.lower_ty(ty);
|
return self.lower_ty(ty);
|
||||||
}
|
}
|
||||||
TyKind::Path(ref qself, ref path) => {
|
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 => {
|
TyKind::ImplicitSelf => {
|
||||||
hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
|
hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
|
||||||
@ -470,7 +471,8 @@ impl<'a> LoweringContext<'a> {
|
|||||||
// Otherwise, the base path is an implicit `Self` type path,
|
// Otherwise, the base path is an implicit `Self` type path,
|
||||||
// e.g. `Vec` in `Vec::new` or `<I as Iterator>::Item` in
|
// e.g. `Vec` in `Vec::new` or `<I as Iterator>::Item` in
|
||||||
// `<I as Iterator>::Item::default`.
|
// `<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",
|
// Anything after the base path are associated "extensions",
|
||||||
@ -493,7 +495,8 @@ impl<'a> LoweringContext<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wrap the associated extension in another type node.
|
// 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.
|
// Should've returned in the for loop above.
|
||||||
@ -2352,12 +2355,33 @@ impl<'a> LoweringContext<'a> {
|
|||||||
self.expr_block(block, attrs)
|
self.expr_block(block, attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty(&mut self, span: Span, node: hir::Ty_) -> P<hir::Ty> {
|
fn ty_path(&mut self, id: NodeId, span: Span, qpath: hir::QPath) -> P<hir::Ty> {
|
||||||
P(hir::Ty {
|
let mut id = id;
|
||||||
id: self.next_id(),
|
let node = match qpath {
|
||||||
node: node,
|
hir::QPath::Resolved(None, path) => {
|
||||||
span: span,
|
// 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 {
|
fn elided_lifetime(&mut self, span: Span) -> hir::Lifetime {
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#![feature(conservative_impl_trait)]
|
#![feature(conservative_impl_trait)]
|
||||||
#![feature(const_fn)]
|
#![feature(const_fn)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
#![feature(field_init_shorthand)]
|
||||||
#![feature(libc)]
|
#![feature(libc)]
|
||||||
#![feature(loop_break_value)]
|
#![feature(loop_break_value)]
|
||||||
#![feature(nonzero)]
|
#![feature(nonzero)]
|
||||||
|
@ -322,24 +322,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||||||
intravisit::walk_ty(this, 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)
|
intravisit::walk_ty(self, ty)
|
||||||
}
|
}
|
||||||
@ -889,7 +871,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||||||
Def::Struct(_) |
|
Def::Struct(_) |
|
||||||
Def::Union(_) |
|
Def::Union(_) |
|
||||||
Def::Enum(_) |
|
Def::Enum(_) |
|
||||||
Def::Trait(_) |
|
|
||||||
Def::PrimTy(_) => return def == path.def,
|
Def::PrimTy(_) => return def == path.def,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -970,21 +951,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, ty: &hir::Ty) {
|
fn visit_ty(&mut self, ty: &hir::Ty) {
|
||||||
let delta = match ty.node {
|
if let hir::TyBareFn(_) = ty.node {
|
||||||
hir::TyBareFn(_) => 1,
|
self.binder_depth += 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
self.binder_depth += delta;
|
|
||||||
intravisit::walk_ty(self, ty);
|
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,
|
fn visit_poly_trait_ref(&mut self,
|
||||||
|
@ -1151,7 +1151,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
rscope: &RegionScope,
|
rscope: &RegionScope,
|
||||||
opt_self_ty: Option<Ty<'tcx>>,
|
opt_self_ty: Option<Ty<'tcx>>,
|
||||||
path: &hir::Path,
|
path: &hir::Path,
|
||||||
path_id: ast::NodeId,
|
|
||||||
permit_variants: bool)
|
permit_variants: bool)
|
||||||
-> Ty<'tcx> {
|
-> Ty<'tcx> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
@ -1161,21 +1160,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
|
|
||||||
let span = path.span;
|
let span = path.span;
|
||||||
match path.def {
|
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) => {
|
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => {
|
||||||
assert_eq!(opt_self_ty, None);
|
assert_eq!(opt_self_ty, None);
|
||||||
tcx.prohibit_type_params(path.segments.split_last().unwrap().1);
|
tcx.prohibit_type_params(path.segments.split_last().unwrap().1);
|
||||||
@ -1421,7 +1405,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
|
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
|
||||||
self.ast_ty_to_ty(rscope, 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)) => {
|
hir::TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => {
|
||||||
debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment);
|
debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment);
|
||||||
|
@ -3976,7 +3976,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
match *qpath {
|
match *qpath {
|
||||||
hir::QPath::Resolved(ref maybe_qself, ref path) => {
|
hir::QPath::Resolved(ref maybe_qself, ref path) => {
|
||||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
|
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)
|
(path.def, ty)
|
||||||
}
|
}
|
||||||
hir::QPath::TypeRelative(ref qself, ref segment) => {
|
hir::QPath::TypeRelative(ref qself, ref segment) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user