diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7ca251f3ff9..f7d40350dc9 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -337,7 +337,8 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { // Otherwise, the base path is an implicit `Self` type path, // e.g. `Vec` in `Vec::new` or `::Item` in // `::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 @@ impl<'a> LoweringContext<'a> { } // 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 @@ impl<'a> LoweringContext<'a> { self.expr_block(block, attrs) } - fn ty(&mut self, span: Span, node: hir::Ty_) -> P { - P(hir::Ty { - id: self.next_id(), - node: node, - span: span, - }) + fn ty_path(&mut self, id: NodeId, span: Span, qpath: hir::QPath) -> P { + 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 { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 11fdf6919cc..0ff9626ae11 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -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)] diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 4e02485a40b..aa118891d98 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -322,24 +322,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { 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 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Def::Struct(_) | Def::Union(_) | Def::Enum(_) | - Def::Trait(_) | Def::PrimTy(_) => return def == path.def, _ => {} } @@ -970,21 +951,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } 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 - } - } - _ => 0 - }; - self.binder_depth += delta; + if let hir::TyBareFn(_) = ty.node { + self.binder_depth += 1; + } 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, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 90efe7cad39..324d569cb8d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1151,7 +1151,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { rscope: &RegionScope, opt_self_ty: Option>, path: &hir::Path, - path_id: ast::NodeId, permit_variants: bool) -> Ty<'tcx> { let tcx = self.tcx(); @@ -1161,21 +1160,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { 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 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { 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); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a8b5d718f81..4d1b2cec32e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3976,7 +3976,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { 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) => {