Implement <T>::method
UFCS expression syntax.
This commit is contained in:
parent
fdfb532d78
commit
d31b9ebef5
40 changed files with 286 additions and 200 deletions
|
@ -437,7 +437,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> {
|
impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> {
|
||||||
fn visit_ty(&mut self, ty: &ast::Ty) {
|
fn visit_ty(&mut self, ty: &ast::Ty) {
|
||||||
if let ast::TyPath(_) = ty.node {
|
if let ast::TyPath(..) = ty.node {
|
||||||
self.check_def(ty.span, ty.id);
|
self.check_def(ty.span, ty.id);
|
||||||
}
|
}
|
||||||
visit::walk_ty(self, ty);
|
visit::walk_ty(self, ty);
|
||||||
|
@ -682,8 +682,8 @@ impl LintPass for PathStatements {
|
||||||
match s.node {
|
match s.node {
|
||||||
ast::StmtSemi(ref expr, _) => {
|
ast::StmtSemi(ref expr, _) => {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) => cx.span_lint(PATH_STATEMENTS, s.span,
|
ast::ExprPath(..) => cx.span_lint(PATH_STATEMENTS, s.span,
|
||||||
"path statement with no effect"),
|
"path statement with no effect"),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1221,7 +1221,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
encode_unsafety(rbml_w, unsafety);
|
encode_unsafety(rbml_w, unsafety);
|
||||||
encode_polarity(rbml_w, polarity);
|
encode_polarity(rbml_w, polarity);
|
||||||
match ty.node {
|
match ty.node {
|
||||||
ast::TyPath(ref path) if path.segments.len() == 1 => {
|
ast::TyPath(None, ref path) if path.segments.len() == 1 => {
|
||||||
let ident = path.segments.last().unwrap().identifier;
|
let ident = path.segments.last().unwrap().identifier;
|
||||||
encode_impl_type_basename(rbml_w, ident);
|
encode_impl_type_basename(rbml_w, ident);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ pub fn prim_ty_to_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||||
|
|
||||||
pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
|
pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
|
||||||
-> Option<Ty<'tcx>> {
|
-> Option<Ty<'tcx>> {
|
||||||
if let ast::TyPath(ref path) = ast_ty.node {
|
if let ast::TyPath(None, ref path) = ast_ty.node {
|
||||||
let def = match tcx.def_map.borrow().get(&ast_ty.id) {
|
let def = match tcx.def_map.borrow().get(&ast_ty.id) {
|
||||||
None => {
|
None => {
|
||||||
tcx.sess.span_bug(ast_ty.span,
|
tcx.sess.span_bug(ast_ty.span,
|
||||||
|
|
|
@ -398,8 +398,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||||
ast::ExprMac(..) |
|
ast::ExprMac(..) |
|
||||||
ast::ExprClosure(..) |
|
ast::ExprClosure(..) |
|
||||||
ast::ExprLit(..) |
|
ast::ExprLit(..) |
|
||||||
ast::ExprPath(..) |
|
ast::ExprPath(..) => {
|
||||||
ast::ExprQPath(..) => {
|
|
||||||
self.straightline(expr, pred, None::<ast::Expr>.iter())
|
self.straightline(expr, pred, None::<ast::Expr>.iter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -439,7 +439,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
|
let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
|
||||||
match def {
|
match def {
|
||||||
Some(def::DefVariant(_, _, _)) => {
|
Some(def::DefVariant(_, _, _)) => {
|
||||||
|
|
|
@ -93,8 +93,8 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
|
||||||
|
|
||||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||||
match e.node {
|
match e.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
match self.def_map.borrow().get(&e.id).map(|d| d.full_def()) {
|
match self.def_map.borrow().get(&e.id).map(|d| d.base_def) {
|
||||||
Some(DefStatic(def_id, _)) |
|
Some(DefStatic(def_id, _)) |
|
||||||
Some(DefConst(def_id)) if
|
Some(DefConst(def_id)) if
|
||||||
ast_util::is_local(def_id) => {
|
ast_util::is_local(def_id) => {
|
||||||
|
|
|
@ -178,7 +178,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
|
||||||
ast::PatVec(pats, None, vec![])
|
ast::PatVec(pats, None, vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprPath(ref path) => {
|
ast::ExprPath(_, ref path) => {
|
||||||
let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
|
let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
|
||||||
match opt_def {
|
match opt_def {
|
||||||
Some(def::DefStruct(..)) =>
|
Some(def::DefStruct(..)) =>
|
||||||
|
@ -194,13 +194,6 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprQPath(_) => {
|
|
||||||
match lookup_const(tcx, expr) {
|
|
||||||
Some(actual) => return const_expr_to_pat(tcx, actual, span),
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => ast::PatLit(P(expr.clone()))
|
_ => ast::PatLit(P(expr.clone()))
|
||||||
};
|
};
|
||||||
P(ast::Pat { id: expr.id, node: pat, span: span })
|
P(ast::Pat { id: expr.id, node: pat, span: span })
|
||||||
|
@ -388,7 +381,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||||
let val = try!(eval_const_expr_partial(tcx, &**base, Some(base_hint)));
|
let val = try!(eval_const_expr_partial(tcx, &**base, Some(base_hint)));
|
||||||
cast_const(val, ety)
|
cast_const(val, ety)
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
|
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
|
||||||
let (const_expr, const_ty) = match opt_def {
|
let (const_expr, const_ty) = match opt_def {
|
||||||
Some(def::DefConst(def_id)) => {
|
Some(def::DefConst(def_id)) => {
|
||||||
|
|
|
@ -175,7 +175,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
||||||
ast::ExprInlineAsm(..) => {
|
ast::ExprInlineAsm(..) => {
|
||||||
self.require_unsafe(expr.span, "use of inline assembly");
|
self.require_unsafe(expr.span, "use of inline assembly");
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
if let def::DefStatic(_, true) = ty::resolve_expr(self.tcx, expr) {
|
if let def::DefStatic(_, true) = ty::resolve_expr(self.tcx, expr) {
|
||||||
self.require_unsafe(expr.span, "use of mutable static");
|
self.require_unsafe(expr.span, "use of mutable static");
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,7 +422,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||||
self.walk_expr(&**subexpr)
|
self.walk_expr(&**subexpr)
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => { }
|
ast::ExprPath(..) => { }
|
||||||
|
|
||||||
ast::ExprUnary(ast::UnDeref, ref base) => { // *base
|
ast::ExprUnary(ast::UnDeref, ref base) => { // *base
|
||||||
if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
|
if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
|
||||||
|
|
|
@ -1233,7 +1233,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
ty_queue.push(&*mut_ty.ty);
|
ty_queue.push(&*mut_ty.ty);
|
||||||
}
|
}
|
||||||
ast::TyPath(ref path) => {
|
ast::TyPath(ref maybe_qself, ref path) => {
|
||||||
let a_def = match self.tcx.def_map.borrow().get(&cur_ty.id) {
|
let a_def = match self.tcx.def_map.borrow().get(&cur_ty.id) {
|
||||||
None => {
|
None => {
|
||||||
self.tcx
|
self.tcx
|
||||||
|
@ -1277,9 +1277,16 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
||||||
region_names: region_names
|
region_names: region_names
|
||||||
};
|
};
|
||||||
let new_path = self.rebuild_path(rebuild_info, lifetime);
|
let new_path = self.rebuild_path(rebuild_info, lifetime);
|
||||||
|
let qself = maybe_qself.as_ref().map(|qself| {
|
||||||
|
ast::QSelf {
|
||||||
|
ty: self.rebuild_arg_ty_or_output(&qself.ty, lifetime,
|
||||||
|
anon_nums, region_names),
|
||||||
|
position: qself.position
|
||||||
|
}
|
||||||
|
});
|
||||||
let to = ast::Ty {
|
let to = ast::Ty {
|
||||||
id: cur_ty.id,
|
id: cur_ty.id,
|
||||||
node: ast::TyPath(new_path),
|
node: ast::TyPath(qself, new_path),
|
||||||
span: cur_ty.span
|
span: cur_ty.span
|
||||||
};
|
};
|
||||||
new_ty = self.rebuild_ty(new_ty, P(to));
|
new_ty = self.rebuild_ty(new_ty, P(to));
|
||||||
|
|
|
@ -445,7 +445,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &ast::Arm) {
|
||||||
fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
|
fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
// live nodes required for uses or definitions of variables:
|
// live nodes required for uses or definitions of variables:
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
let def = ir.tcx.def_map.borrow()[expr.id].full_def();
|
let def = ir.tcx.def_map.borrow()[expr.id].full_def();
|
||||||
debug!("expr {}: path that leads to {:?}", expr.id, def);
|
debug!("expr {}: path that leads to {:?}", expr.id, def);
|
||||||
if let DefLocal(..) = def {
|
if let DefLocal(..) = def {
|
||||||
|
@ -947,7 +947,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
// Interesting cases with control flow or which gen/kill
|
// Interesting cases with control flow or which gen/kill
|
||||||
|
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
self.access_path(expr, succ, ACC_READ | ACC_USE)
|
self.access_path(expr, succ, ACC_READ | ACC_USE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1275,7 +1275,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
// just ignore such cases and treat them as reads.
|
// just ignore such cases and treat them as reads.
|
||||||
|
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => succ,
|
ast::ExprPath(..) => succ,
|
||||||
ast::ExprField(ref e, _) => self.propagate_through_expr(&**e, succ),
|
ast::ExprField(ref e, _) => self.propagate_through_expr(&**e, succ),
|
||||||
ast::ExprTupField(ref e, _) => self.propagate_through_expr(&**e, succ),
|
ast::ExprTupField(ref e, _) => self.propagate_through_expr(&**e, succ),
|
||||||
_ => self.propagate_through_expr(expr, succ)
|
_ => self.propagate_through_expr(expr, succ)
|
||||||
|
@ -1286,7 +1286,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
|
fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
|
||||||
-> LiveNode {
|
-> LiveNode {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
self.access_path(expr, succ, acc)
|
self.access_path(expr, succ, acc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1468,7 +1468,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
|
||||||
ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
|
ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
|
||||||
ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
|
ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
|
||||||
ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) |
|
ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) |
|
||||||
ast::ExprRange(..) | ast::ExprQPath(..) => {
|
ast::ExprRange(..) => {
|
||||||
visit::walk_expr(this, expr);
|
visit::walk_expr(this, expr);
|
||||||
}
|
}
|
||||||
ast::ExprIfLet(..) => {
|
ast::ExprIfLet(..) => {
|
||||||
|
@ -1561,7 +1561,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
|
|
||||||
fn check_lvalue(&mut self, expr: &Expr) {
|
fn check_lvalue(&mut self, expr: &Expr) {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
if let DefLocal(nid) = self.ir.tcx.def_map.borrow()[expr.id].full_def() {
|
if let DefLocal(nid) = self.ir.tcx.def_map.borrow()[expr.id].full_def() {
|
||||||
// Assignment to an immutable variable or argument: only legal
|
// Assignment to an immutable variable or argument: only legal
|
||||||
// if there is no later assignment. If this local is actually
|
// if there is no later assignment. If this local is actually
|
||||||
|
|
|
@ -529,7 +529,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
let def = self.tcx().def_map.borrow()[expr.id].full_def();
|
let def = self.tcx().def_map.borrow()[expr.id].full_def();
|
||||||
self.cat_def(expr.id, expr.span, expr_ty, def)
|
self.cat_def(expr.id, expr.span, expr_ty, def)
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
|
||||||
fn visit_expr(&mut self, expr: &ast::Expr) {
|
fn visit_expr(&mut self, expr: &ast::Expr) {
|
||||||
|
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
let def = match self.tcx.def_map.borrow().get(&expr.id) {
|
let def = match self.tcx.def_map.borrow().get(&expr.id) {
|
||||||
Some(d) => d.full_def(),
|
Some(d) => d.full_def(),
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -165,7 +165,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||||
visit::walk_ty(this, ty);
|
visit::walk_ty(this, ty);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ast::TyPath(ref path) => {
|
ast::TyPath(None, ref path) => {
|
||||||
// if this path references a trait, then this will resolve to
|
// if this path references a trait, then this will resolve to
|
||||||
// a trait ref, which introduces a binding scope.
|
// a trait ref, which introduces a binding scope.
|
||||||
match self.def_map.borrow().get(&ty.id).map(|d| (d.base_def, d.depth)) {
|
match self.def_map.borrow().get(&ty.id).map(|d| (d.base_def, d.depth)) {
|
||||||
|
|
|
@ -4550,7 +4550,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
match resolve_expr(tcx, expr) {
|
match resolve_expr(tcx, expr) {
|
||||||
def::DefVariant(tid, vid, _) => {
|
def::DefVariant(tid, vid, _) => {
|
||||||
let variant_info = enum_variant_with_id(tcx, tid, vid);
|
let variant_info = enum_variant_with_id(tcx, tid, vid);
|
||||||
|
@ -5838,7 +5838,7 @@ pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let found = match count_expr.node {
|
let found = match count_expr.node {
|
||||||
ast::ExprPath(ast::Path {
|
ast::ExprPath(None, ast::Path {
|
||||||
global: false,
|
global: false,
|
||||||
ref segments,
|
ref segments,
|
||||||
..
|
..
|
||||||
|
|
|
@ -244,8 +244,7 @@ mod svh_visitor {
|
||||||
SawExprAssignOp(ast::BinOp_),
|
SawExprAssignOp(ast::BinOp_),
|
||||||
SawExprIndex,
|
SawExprIndex,
|
||||||
SawExprRange,
|
SawExprRange,
|
||||||
SawExprPath,
|
SawExprPath(Option<usize>),
|
||||||
SawExprQPath,
|
|
||||||
SawExprAddrOf(ast::Mutability),
|
SawExprAddrOf(ast::Mutability),
|
||||||
SawExprRet,
|
SawExprRet,
|
||||||
SawExprInlineAsm(&'a ast::InlineAsm),
|
SawExprInlineAsm(&'a ast::InlineAsm),
|
||||||
|
@ -277,8 +276,7 @@ mod svh_visitor {
|
||||||
ExprTupField(_, id) => SawExprTupField(id.node),
|
ExprTupField(_, id) => SawExprTupField(id.node),
|
||||||
ExprIndex(..) => SawExprIndex,
|
ExprIndex(..) => SawExprIndex,
|
||||||
ExprRange(..) => SawExprRange,
|
ExprRange(..) => SawExprRange,
|
||||||
ExprPath(..) => SawExprPath,
|
ExprPath(ref qself, _) => SawExprPath(qself.as_ref().map(|q| q.position)),
|
||||||
ExprQPath(..) => SawExprQPath,
|
|
||||||
ExprAddrOf(m, _) => SawExprAddrOf(m),
|
ExprAddrOf(m, _) => SawExprAddrOf(m),
|
||||||
ExprBreak(id) => SawExprBreak(id.map(content)),
|
ExprBreak(id) => SawExprBreak(id.map(content)),
|
||||||
ExprAgain(id) => SawExprAgain(id.map(content)),
|
ExprAgain(id) => SawExprAgain(id.map(content)),
|
||||||
|
|
|
@ -258,7 +258,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||||
// * Private trait impls for private types can be completely ignored
|
// * Private trait impls for private types can be completely ignored
|
||||||
ast::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
|
ast::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
|
||||||
let public_ty = match ty.node {
|
let public_ty = match ty.node {
|
||||||
ast::TyPath(_) => {
|
ast::TyPath(..) => {
|
||||||
match self.tcx.def_map.borrow()[ty.id].full_def() {
|
match self.tcx.def_map.borrow()[ty.id].full_def() {
|
||||||
def::DefPrimTy(..) => true,
|
def::DefPrimTy(..) => true,
|
||||||
def => {
|
def => {
|
||||||
|
@ -325,7 +325,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ItemTy(ref ty, _) if public_first => {
|
ast::ItemTy(ref ty, _) if public_first => {
|
||||||
if let ast::TyPath(_) = ty.node {
|
if let ast::TyPath(..) = ty.node {
|
||||||
match self.tcx.def_map.borrow()[ty.id].full_def() {
|
match self.tcx.def_map.borrow()[ty.id].full_def() {
|
||||||
def::DefPrimTy(..) | def::DefTyParam(..) => {},
|
def::DefPrimTy(..) | def::DefTyParam(..) => {},
|
||||||
def => {
|
def => {
|
||||||
|
@ -627,7 +627,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||||
// was private.
|
// was private.
|
||||||
ast::ItemImpl(_, _, _, _, ref ty, _) => {
|
ast::ItemImpl(_, _, _, _, ref ty, _) => {
|
||||||
match ty.node {
|
match ty.node {
|
||||||
ast::TyPath(_) => {}
|
ast::TyPath(..) => {}
|
||||||
_ => return Some((err_span, err_msg, None)),
|
_ => return Some((err_span, err_msg, None)),
|
||||||
};
|
};
|
||||||
let def = self.tcx.def_map.borrow()[ty.id].full_def();
|
let def = self.tcx.def_map.borrow()[ty.id].full_def();
|
||||||
|
@ -908,7 +908,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||||
struct type?!"),
|
struct type?!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
let guard = |did: ast::DefId| {
|
let guard = |did: ast::DefId| {
|
||||||
let fields = ty::lookup_struct_fields(self.tcx, did);
|
let fields = ty::lookup_struct_fields(self.tcx, did);
|
||||||
let any_priv = fields.iter().any(|f| {
|
let any_priv = fields.iter().any(|f| {
|
||||||
|
@ -1254,7 +1254,7 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
|
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
|
||||||
fn visit_ty(&mut self, ty: &ast::Ty) {
|
fn visit_ty(&mut self, ty: &ast::Ty) {
|
||||||
if let ast::TyPath(_) = ty.node {
|
if let ast::TyPath(..) = ty.node {
|
||||||
if self.inner.path_is_private_type(ty.id) {
|
if self.inner.path_is_private_type(ty.id) {
|
||||||
self.contains_private = true;
|
self.contains_private = true;
|
||||||
// found what we're looking for so let's stop
|
// found what we're looking for so let's stop
|
||||||
|
@ -1460,7 +1460,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: &ast::Ty) {
|
fn visit_ty(&mut self, t: &ast::Ty) {
|
||||||
if let ast::TyPath(ref p) = t.node {
|
if let ast::TyPath(_, ref p) = t.node {
|
||||||
if !self.tcx.sess.features.borrow().visible_private_types &&
|
if !self.tcx.sess.features.borrow().visible_private_types &&
|
||||||
self.path_is_private_type(t.id) {
|
self.path_is_private_type(t.id) {
|
||||||
self.tcx.sess.span_err(p.span,
|
self.tcx.sess.span_err(p.span,
|
||||||
|
|
|
@ -65,7 +65,7 @@ use rustc::util::lev_distance::lev_distance;
|
||||||
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
|
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
|
||||||
use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
|
use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
|
||||||
use syntax::ast::{ExprLoop, ExprWhile, ExprMethodCall};
|
use syntax::ast::{ExprLoop, ExprWhile, ExprMethodCall};
|
||||||
use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl};
|
use syntax::ast::{ExprPath, ExprStruct, FnDecl};
|
||||||
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
|
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
|
||||||
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
|
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
|
||||||
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
|
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
|
||||||
|
@ -75,7 +75,7 @@ use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
|
||||||
use syntax::ast::{PatRange, PatStruct, Path, PrimTy};
|
use syntax::ast::{PatRange, PatStruct, Path, PrimTy};
|
||||||
use syntax::ast::{TraitRef, Ty, TyBool, TyChar, TyF32};
|
use syntax::ast::{TraitRef, Ty, TyBool, TyChar, TyF32};
|
||||||
use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt};
|
use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt};
|
||||||
use syntax::ast::{TyPath, TyPtr, TyQPath};
|
use syntax::ast::{TyPath, TyPtr};
|
||||||
use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
|
use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
|
||||||
use syntax::ast::{TypeImplItem};
|
use syntax::ast::{TypeImplItem};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
@ -2821,7 +2821,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
FnSpace,
|
FnSpace,
|
||||||
MethodRibKind)
|
MethodRibKind)
|
||||||
}
|
}
|
||||||
ast::TypeTraitItem(_) => NoTypeParameters,
|
ast::TypeTraitItem(ref assoc_ty) => {
|
||||||
|
let ty_param = &assoc_ty.ty_param;
|
||||||
|
this.check_if_primitive_type_name(ty_param.ident.name,
|
||||||
|
ty_param.span);
|
||||||
|
NoTypeParameters
|
||||||
|
}
|
||||||
};
|
};
|
||||||
this.with_type_parameter_rib(type_parameters, |this| {
|
this.with_type_parameter_rib(type_parameters, |this| {
|
||||||
visit::walk_trait_item(this, trait_item)
|
visit::walk_trait_item(this, trait_item)
|
||||||
|
@ -3243,14 +3248,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
fn resolve_type(&mut self, ty: &Ty) {
|
fn resolve_type(&mut self, ty: &Ty) {
|
||||||
match ty.node {
|
match ty.node {
|
||||||
// Like path expressions, the interpretation of path types depends
|
// `<T>::a::b::c` is resolved by typeck alone.
|
||||||
// on whether the path has multiple elements in it or not.
|
TyPath(Some(ast::QSelf { position: 0, .. }), _) => {}
|
||||||
|
|
||||||
TyPath(ref path) | TyQPath(ast::QPath { ref path, .. }) => {
|
TyPath(ref maybe_qself, ref path) => {
|
||||||
let max_assoc_types = if let TyQPath(_) = ty.node {
|
let max_assoc_types = if let Some(ref qself) = *maybe_qself {
|
||||||
// Make sure the trait is valid.
|
// Make sure the trait is valid.
|
||||||
let _ = self.resolve_trait_reference(ty.id, path, 1);
|
let _ = self.resolve_trait_reference(ty.id, path, 1);
|
||||||
1
|
path.segments.len() - qself.position
|
||||||
} else {
|
} else {
|
||||||
path.segments.len()
|
path.segments.len()
|
||||||
};
|
};
|
||||||
|
@ -3284,10 +3289,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
// Keep reporting some errors even if they're ignored above.
|
// Keep reporting some errors even if they're ignored above.
|
||||||
self.resolve_path(ty.id, path, 0, TypeNS, true);
|
self.resolve_path(ty.id, path, 0, TypeNS, true);
|
||||||
|
|
||||||
let kind = match ty.node {
|
let kind = if maybe_qself.is_some() {
|
||||||
TyQPath(_) => "associated type",
|
"associated type"
|
||||||
_ => "type name"
|
} else {
|
||||||
|
"type name"
|
||||||
};
|
};
|
||||||
|
|
||||||
let msg = format!("use of undeclared {} `{}`", kind,
|
let msg = format!("use of undeclared {} `{}`", kind,
|
||||||
self.path_names_to_string(path, 0));
|
self.path_names_to_string(path, 0));
|
||||||
self.resolve_error(ty.span, &msg[..]);
|
self.resolve_error(ty.span, &msg[..]);
|
||||||
|
@ -3905,7 +3912,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
|
fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
|
||||||
-> Option<(Path, NodeId, FallbackChecks)> {
|
-> Option<(Path, NodeId, FallbackChecks)> {
|
||||||
match t.node {
|
match t.node {
|
||||||
TyPath(ref path) => Some((path.clone(), t.id, allow)),
|
TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
|
||||||
TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
|
TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
|
||||||
TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
|
TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
|
||||||
// This doesn't handle the remaining `Ty` variants as they are not
|
// This doesn't handle the remaining `Ty` variants as they are not
|
||||||
|
@ -4063,14 +4070,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
// Next, resolve the node.
|
// Next, resolve the node.
|
||||||
match expr.node {
|
match expr.node {
|
||||||
// The interpretation of paths depends on whether the path has
|
// `<T>::a::b::c` is resolved by typeck alone.
|
||||||
// multiple elements in it or not.
|
ExprPath(Some(ast::QSelf { position: 0, .. }), ref path) => {
|
||||||
|
let method_name = path.segments.last().unwrap().identifier.name;
|
||||||
|
let traits = self.search_for_traits_containing_method(method_name);
|
||||||
|
self.trait_map.insert(expr.id, traits);
|
||||||
|
visit::walk_expr(self, expr);
|
||||||
|
}
|
||||||
|
|
||||||
ExprPath(ref path) | ExprQPath(ast::QPath { ref path, .. }) => {
|
ExprPath(ref maybe_qself, ref path) => {
|
||||||
let max_assoc_types = if let ExprQPath(_) = expr.node {
|
let max_assoc_types = if let Some(ref qself) = *maybe_qself {
|
||||||
// Make sure the trait is valid.
|
// Make sure the trait is valid.
|
||||||
let _ = self.resolve_trait_reference(expr.id, path, 1);
|
let _ = self.resolve_trait_reference(expr.id, path, 1);
|
||||||
1
|
path.segments.len() - qself.position
|
||||||
} else {
|
} else {
|
||||||
path.segments.len()
|
path.segments.len()
|
||||||
};
|
};
|
||||||
|
|
|
@ -659,7 +659,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||||
let trait_id = trait_ref.as_ref().and_then(|tr| self.lookup_type_ref(tr.ref_id));
|
let trait_id = trait_ref.as_ref().and_then(|tr| self.lookup_type_ref(tr.ref_id));
|
||||||
match typ.node {
|
match typ.node {
|
||||||
// Common case impl for a struct or something basic.
|
// Common case impl for a struct or something basic.
|
||||||
ast::TyPath(ref path) => {
|
ast::TyPath(None, ref path) => {
|
||||||
let sub_span = self.span.sub_span_for_type_name(path.span);
|
let sub_span = self.span.sub_span_for_type_name(path.span);
|
||||||
let self_id = self.lookup_type_ref(typ.id).map(|id| {
|
let self_id = self.lookup_type_ref(typ.id).map(|id| {
|
||||||
self.fmt.ref_str(recorder::TypeRef,
|
self.fmt.ref_str(recorder::TypeRef,
|
||||||
|
@ -1306,7 +1306,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match t.node {
|
match t.node {
|
||||||
ast::TyPath(ref path) => {
|
ast::TyPath(_, ref path) => {
|
||||||
match self.lookup_type_ref(t.id) {
|
match self.lookup_type_ref(t.id) {
|
||||||
Some(id) => {
|
Some(id) => {
|
||||||
let sub_span = self.span.sub_span_for_type_name(t.span);
|
let sub_span = self.span.sub_span_for_type_name(t.span);
|
||||||
|
@ -1338,7 +1338,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
||||||
// because just walking the callee path does what we want.
|
// because just walking the callee path does what we want.
|
||||||
visit::walk_expr(self, ex);
|
visit::walk_expr(self, ex);
|
||||||
}
|
}
|
||||||
ast::ExprPath(ref path) | ast::ExprQPath(ast::QPath { ref path, .. }) => {
|
ast::ExprPath(_, ref path) => {
|
||||||
self.process_path(ex.id, path.span, path, None);
|
self.process_path(ex.id, path.span, path, None);
|
||||||
visit::walk_expr(self, ex);
|
visit::walk_expr(self, ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1277,7 +1277,7 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
/// Checks whether the binding in `discr` is assigned to anywhere in the expression `body`
|
/// Checks whether the binding in `discr` is assigned to anywhere in the expression `body`
|
||||||
fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
|
fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
|
||||||
let (vid, field) = match discr.node {
|
let (vid, field) = match discr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => match bcx.def(discr.id) {
|
ast::ExprPath(..) => match bcx.def(discr.id) {
|
||||||
def::DefLocal(vid) | def::DefUpvar(vid, _) => (vid, None),
|
def::DefLocal(vid) | def::DefUpvar(vid, _) => (vid, None),
|
||||||
_ => return false
|
_ => return false
|
||||||
},
|
},
|
||||||
|
|
|
@ -93,7 +93,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
|
||||||
|
|
||||||
// pick out special kinds of expressions that can be called:
|
// pick out special kinds of expressions that can be called:
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
return trans_def(bcx, bcx.def(expr.id), expr);
|
return trans_def(bcx, bcx.def(expr.id), expr);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -193,7 +193,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
// Special-case constants to cache a common global for all uses.
|
// Special-case constants to cache a common global for all uses.
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
let def = ccx.tcx().def_map.borrow()[expr.id].full_def();
|
let def = ccx.tcx().def_map.borrow()[expr.id].full_def();
|
||||||
match def {
|
match def {
|
||||||
def::DefConst(def_id) => {
|
def::DefConst(def_id) => {
|
||||||
|
@ -663,7 +663,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
C_array(llunitty, &vs[..])
|
C_array(llunitty, &vs[..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
let def = cx.tcx().def_map.borrow()[e.id].full_def();
|
let def = cx.tcx().def_map.borrow()[e.id].full_def();
|
||||||
match def {
|
match def {
|
||||||
def::DefFn(..) | def::DefMethod(..) => {
|
def::DefFn(..) | def::DefMethod(..) => {
|
||||||
|
|
|
@ -3487,8 +3487,7 @@ fn create_scope_map(cx: &CrateContext,
|
||||||
ast::ExprLit(_) |
|
ast::ExprLit(_) |
|
||||||
ast::ExprBreak(_) |
|
ast::ExprBreak(_) |
|
||||||
ast::ExprAgain(_) |
|
ast::ExprAgain(_) |
|
||||||
ast::ExprPath(_) |
|
ast::ExprPath(..) => {}
|
||||||
ast::ExprQPath(_) => {}
|
|
||||||
|
|
||||||
ast::ExprCast(ref sub_exp, _) |
|
ast::ExprCast(ref sub_exp, _) |
|
||||||
ast::ExprAddrOf(_, ref sub_exp) |
|
ast::ExprAddrOf(_, ref sub_exp) |
|
||||||
|
|
|
@ -143,7 +143,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
// it prefers in-place instantiation, likely because it contains
|
// it prefers in-place instantiation, likely because it contains
|
||||||
// `[x; N]` somewhere within.
|
// `[x; N]` somewhere within.
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
match bcx.def(expr.id) {
|
match bcx.def(expr.id) {
|
||||||
def::DefConst(did) => {
|
def::DefConst(did) => {
|
||||||
let expr = consts::get_const_expr(bcx.ccx(), did, expr);
|
let expr = consts::get_const_expr(bcx.ccx(), did, expr);
|
||||||
|
@ -629,7 +629,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
ast::ExprParen(ref e) => {
|
ast::ExprParen(ref e) => {
|
||||||
trans(bcx, &**e)
|
trans(bcx, &**e)
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
trans_def(bcx, expr, bcx.def(expr.id))
|
trans_def(bcx, expr, bcx.def(expr.id))
|
||||||
}
|
}
|
||||||
ast::ExprField(ref base, ident) => {
|
ast::ExprField(ref base, ident) => {
|
||||||
|
@ -1033,7 +1033,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
ast::ExprParen(ref e) => {
|
ast::ExprParen(ref e) => {
|
||||||
trans_into(bcx, &**e, dest)
|
trans_into(bcx, &**e, dest)
|
||||||
}
|
}
|
||||||
ast::ExprPath(_) | ast::ExprQPath(_) => {
|
ast::ExprPath(..) => {
|
||||||
trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
|
trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
|
||||||
}
|
}
|
||||||
ast::ExprIf(ref cond, ref thn, ref els) => {
|
ast::ExprIf(ref cond, ref thn, ref els) => {
|
||||||
|
|
|
@ -52,6 +52,7 @@ use middle::astconv_util::{prim_ty_to_ty, check_path_args, NO_TPS, NO_REGIONS};
|
||||||
use middle::const_eval;
|
use middle::const_eval;
|
||||||
use middle::def;
|
use middle::def;
|
||||||
use middle::resolve_lifetime as rl;
|
use middle::resolve_lifetime as rl;
|
||||||
|
use middle::privacy::{AllPublic, LastMod};
|
||||||
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
|
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
|
||||||
use middle::traits;
|
use middle::traits;
|
||||||
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
|
use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
|
||||||
|
@ -897,7 +898,7 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
match ty.node {
|
match ty.node {
|
||||||
ast::TyPath(ref path) => {
|
ast::TyPath(None, ref path) => {
|
||||||
let def = this.tcx().def_map.borrow().get(&ty.id).map(|d| d.full_def());
|
let def = this.tcx().def_map.borrow().get(&ty.id).map(|d| d.full_def());
|
||||||
match def {
|
match def {
|
||||||
Some(def::DefTrait(trait_def_id)) => {
|
Some(def::DefTrait(trait_def_id)) => {
|
||||||
|
@ -981,7 +982,13 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||||
check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS);
|
check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS);
|
||||||
let assoc_name = item_segment.identifier.name;
|
let assoc_name = item_segment.identifier.name;
|
||||||
|
|
||||||
let ty_param_node_id = if let ty::ty_param(_) = ty.sty {
|
let is_param = match (&ty.sty, ty_path_def) {
|
||||||
|
(&ty::ty_param(_), def::DefTyParam(..)) |
|
||||||
|
(&ty::ty_param(_), def::DefSelfTy(_)) => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
|
||||||
|
let ty_param_node_id = if is_param {
|
||||||
ty_path_def.local_node_id()
|
ty_path_def.local_node_id()
|
||||||
} else {
|
} else {
|
||||||
span_err!(tcx.sess, span, E0223,
|
span_err!(tcx.sess, span, E0223,
|
||||||
|
@ -1195,9 +1202,14 @@ pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||||
segments.last().unwrap())
|
segments.last().unwrap())
|
||||||
}
|
}
|
||||||
def::DefMod(id) => {
|
def::DefMod(id) => {
|
||||||
tcx.sess.span_bug(span,
|
// Used as sentinel by callers to indicate the `<T>::a::b::c` form.
|
||||||
&format!("found module name used as a type: {}",
|
if segments.is_empty() {
|
||||||
tcx.map.node_to_string(id.node)));
|
opt_self_ty.expect("missing T in <T>::a::b::c")
|
||||||
|
} else {
|
||||||
|
tcx.sess.span_bug(span,
|
||||||
|
&format!("found module name used as a type: {}",
|
||||||
|
tcx.map.node_to_string(id.node)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
def::DefPrimTy(prim_ty) => {
|
def::DefPrimTy(prim_ty) => {
|
||||||
prim_ty_to_ty(tcx, segments, prim_ty)
|
prim_ty_to_ty(tcx, segments, prim_ty)
|
||||||
|
@ -1302,20 +1314,25 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
|
||||||
ast::TyPolyTraitRef(ref bounds) => {
|
ast::TyPolyTraitRef(ref bounds) => {
|
||||||
conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds)
|
conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds)
|
||||||
}
|
}
|
||||||
ast::TyPath(ref path) | ast::TyQPath(ast::QPath { ref path, .. }) => {
|
ast::TyPath(ref maybe_qself, ref path) => {
|
||||||
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
|
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
|
||||||
d
|
d
|
||||||
|
} else if let Some(ast::QSelf { position: 0, .. }) = *maybe_qself {
|
||||||
|
// Create some fake resolution that can't possibly be a type.
|
||||||
|
def::PathResolution {
|
||||||
|
base_def: def::DefMod(ast_util::local_def(ast::CRATE_NODE_ID)),
|
||||||
|
last_private: LastMod(AllPublic),
|
||||||
|
depth: path.segments.len()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tcx.sess.span_bug(ast_ty.span,
|
tcx.sess.span_bug(ast_ty.span,
|
||||||
&format!("unbound path {}", ast_ty.repr(tcx)))
|
&format!("unbound path {}", ast_ty.repr(tcx)))
|
||||||
};
|
};
|
||||||
let mut def = path_res.base_def;
|
let mut def = path_res.base_def;
|
||||||
let base_ty_end = path.segments.len() - path_res.depth;
|
let base_ty_end = path.segments.len() - path_res.depth;
|
||||||
let opt_self_ty = if let ast::TyQPath(ref qpath) = ast_ty.node {
|
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
|
||||||
Some(ast_ty_to_ty(this, rscope, &*qpath.self_type))
|
ast_ty_to_ty(this, rscope, &qself.ty)
|
||||||
} else {
|
});
|
||||||
None
|
|
||||||
};
|
|
||||||
let ty = finish_resolving_def_to_ty(this, rscope, ast_ty.span,
|
let ty = finish_resolving_def_to_ty(this, rscope, ast_ty.span,
|
||||||
PathParamMode::Explicit, &mut def,
|
PathParamMode::Explicit, &mut def,
|
||||||
opt_self_ty,
|
opt_self_ty,
|
||||||
|
|
|
@ -91,6 +91,7 @@ use middle::infer;
|
||||||
use middle::mem_categorization as mc;
|
use middle::mem_categorization as mc;
|
||||||
use middle::mem_categorization::McResult;
|
use middle::mem_categorization::McResult;
|
||||||
use middle::pat_util::{self, pat_id_map};
|
use middle::pat_util::{self, pat_id_map};
|
||||||
|
use middle::privacy::{AllPublic, LastMod};
|
||||||
use middle::region::{self, CodeExtent};
|
use middle::region::{self, CodeExtent};
|
||||||
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
|
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
|
||||||
use middle::traits;
|
use middle::traits;
|
||||||
|
@ -3397,7 +3398,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
|
|
||||||
let mut checked = false;
|
let mut checked = false;
|
||||||
opt_place.as_ref().map(|place| match place.node {
|
opt_place.as_ref().map(|place| match place.node {
|
||||||
ast::ExprPath(ref path) => {
|
ast::ExprPath(None, ref path) => {
|
||||||
// FIXME(pcwalton): For now we hardcode the two permissible
|
// FIXME(pcwalton): For now we hardcode the two permissible
|
||||||
// places: the exchange heap and the managed heap.
|
// places: the exchange heap and the managed heap.
|
||||||
let definition = lookup_def(fcx, path.span, place.id);
|
let definition = lookup_def(fcx, path.span, place.id);
|
||||||
|
@ -3590,16 +3591,21 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
};
|
};
|
||||||
fcx.write_ty(id, oprnd_t);
|
fcx.write_ty(id, oprnd_t);
|
||||||
}
|
}
|
||||||
ast::ExprPath(ref path) | ast::ExprQPath(ast::QPath { ref path, .. }) => {
|
ast::ExprPath(ref maybe_qself, ref path) => {
|
||||||
let opt_self_ty = if let ast::ExprQPath(ref qpath) = expr.node {
|
let opt_self_ty = maybe_qself.as_ref().map(|qself| {
|
||||||
Some(fcx.to_ty(&*qpath.self_type))
|
fcx.to_ty(&qself.ty)
|
||||||
} else {
|
});
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
|
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
|
||||||
d
|
d
|
||||||
} else {
|
} else if let Some(ast::QSelf { position: 0, .. }) = *maybe_qself {
|
||||||
|
// Create some fake resolution that can't possibly be a type.
|
||||||
|
def::PathResolution {
|
||||||
|
base_def: def::DefMod(local_def(ast::CRATE_NODE_ID)),
|
||||||
|
last_private: LastMod(AllPublic),
|
||||||
|
depth: path.segments.len()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
tcx.sess.span_bug(expr.span,
|
tcx.sess.span_bug(expr.span,
|
||||||
&format!("unbound path {}", expr.repr(tcx))[])
|
&format!("unbound path {}", expr.repr(tcx))[])
|
||||||
};
|
};
|
||||||
|
|
|
@ -1683,20 +1683,15 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
|
||||||
index: u32)
|
index: u32)
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
match ast_ty.node {
|
if let ast::TyPath(None, _) = ast_ty.node {
|
||||||
ast::TyPath(_) => {
|
let path_res = ccx.tcx.def_map.borrow()[ast_ty.id];
|
||||||
match ccx.tcx.def_map.borrow()[ast_ty.id] {
|
if let def::DefTyParam(s, i, _, _) = path_res.base_def {
|
||||||
def::DefTyParam(s, i, _, _) => {
|
path_res.depth == 0 && space == s && index == i
|
||||||
space == s && index == i
|
} else {
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1494,15 +1494,15 @@ impl Clean<Type> for ast::Ty {
|
||||||
TyFixedLengthVec(ref ty, ref e) => FixedVector(box ty.clean(cx),
|
TyFixedLengthVec(ref ty, ref e) => FixedVector(box ty.clean(cx),
|
||||||
e.span.to_src(cx)),
|
e.span.to_src(cx)),
|
||||||
TyTup(ref tys) => Tuple(tys.clean(cx)),
|
TyTup(ref tys) => Tuple(tys.clean(cx)),
|
||||||
TyPath(ref p) => {
|
TyPath(None, ref p) => {
|
||||||
resolve_type(cx, p.clean(cx), self.id)
|
resolve_type(cx, p.clean(cx), self.id)
|
||||||
}
|
}
|
||||||
TyQPath(ref qp) => {
|
TyPath(Some(ref qself), ref p) => {
|
||||||
let mut trait_path = qp.path.clone();
|
let mut trait_path = p.clone();
|
||||||
trait_path.segments.pop();
|
trait_path.segments.pop();
|
||||||
Type::QPath {
|
Type::QPath {
|
||||||
name: qp.path.segments.last().unwrap().identifier.clean(cx),
|
name: p.segments.last().unwrap().identifier.clean(cx),
|
||||||
self_type: box qp.self_type.clean(cx),
|
self_type: box qself.ty.clean(cx),
|
||||||
trait_: box resolve_type(cx, trait_path.clean(cx), self.id)
|
trait_: box resolve_type(cx, trait_path.clean(cx), self.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -753,11 +753,10 @@ pub enum Expr_ {
|
||||||
ExprIndex(P<Expr>, P<Expr>),
|
ExprIndex(P<Expr>, P<Expr>),
|
||||||
ExprRange(Option<P<Expr>>, Option<P<Expr>>),
|
ExprRange(Option<P<Expr>>, Option<P<Expr>>),
|
||||||
|
|
||||||
/// Variable reference, possibly containing `::` and/or
|
/// Variable reference, possibly containing `::` and/or type
|
||||||
/// type parameters, e.g. foo::bar::<baz>
|
/// parameters, e.g. foo::bar::<baz>. Optionally "qualified",
|
||||||
ExprPath(Path),
|
/// e.g. `<Vec<T> as SomeTrait>::SomeType`.
|
||||||
/// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
|
ExprPath(Option<QSelf>, Path),
|
||||||
ExprQPath(QPath),
|
|
||||||
|
|
||||||
ExprAddrOf(Mutability, P<Expr>),
|
ExprAddrOf(Mutability, P<Expr>),
|
||||||
ExprBreak(Option<Ident>),
|
ExprBreak(Option<Ident>),
|
||||||
|
@ -778,15 +777,22 @@ pub enum Expr_ {
|
||||||
ExprParen(P<Expr>)
|
ExprParen(P<Expr>)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A "qualified path":
|
/// The explicit Self type in a "qualified path". The actual
|
||||||
|
/// path, including the trait and the associated item, is stored
|
||||||
|
/// sepparately. `position` represents the index of the associated
|
||||||
|
/// item qualified with this Self type.
|
||||||
///
|
///
|
||||||
/// <Vec<T> as SomeTrait>::SomeAssociatedItem
|
/// <Vec<T> as a::b::Trait>::AssociatedItem
|
||||||
/// ^~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
/// ^~~~~ ~~~~~~~~~~~~~~^
|
||||||
/// self_type path
|
/// ty position = 3
|
||||||
|
///
|
||||||
|
/// <Vec<T>>::AssociatedItem
|
||||||
|
/// ^~~~~ ^
|
||||||
|
/// ty position = 0
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub struct QPath {
|
pub struct QSelf {
|
||||||
pub self_type: P<Ty>,
|
pub ty: P<Ty>,
|
||||||
pub path: Path,
|
pub position: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
||||||
|
@ -1253,12 +1259,11 @@ pub enum Ty_ {
|
||||||
TyBareFn(P<BareFnTy>),
|
TyBareFn(P<BareFnTy>),
|
||||||
/// A tuple (`(A, B, C, D,...)`)
|
/// A tuple (`(A, B, C, D,...)`)
|
||||||
TyTup(Vec<P<Ty>> ),
|
TyTup(Vec<P<Ty>> ),
|
||||||
/// A path (`module::module::...::Type`) or primitive
|
/// A path (`module::module::...::Type`), optionally
|
||||||
|
/// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
|
||||||
///
|
///
|
||||||
/// Type parameters are stored in the Path itself
|
/// Type parameters are stored in the Path itself
|
||||||
TyPath(Path),
|
TyPath(Option<QSelf>, Path),
|
||||||
/// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
|
|
||||||
TyQPath(QPath),
|
|
||||||
/// Something like `A+B`. Note that `B` must always be a path.
|
/// Something like `A+B`. Note that `B` must always be a path.
|
||||||
TyObjectSum(P<Ty>, TyParamBounds),
|
TyObjectSum(P<Ty>, TyParamBounds),
|
||||||
/// A type like `for<'a> Foo<&'a Bar>`
|
/// A type like `for<'a> Foo<&'a Bar>`
|
||||||
|
|
|
@ -134,7 +134,7 @@ pub fn unop_to_string(op: UnOp) -> &'static str {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_path(e: P<Expr>) -> bool {
|
pub fn is_path(e: P<Expr>) -> bool {
|
||||||
return match e.node { ExprPath(_) => true, _ => false };
|
match e.node { ExprPath(..) => true, _ => false }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a string representation of a signed int type, with its value.
|
/// Get a string representation of a signed int type, with its value.
|
||||||
|
|
|
@ -43,14 +43,14 @@ pub trait AstBuilder {
|
||||||
fn qpath(&self, self_type: P<ast::Ty>,
|
fn qpath(&self, self_type: P<ast::Ty>,
|
||||||
trait_path: ast::Path,
|
trait_path: ast::Path,
|
||||||
ident: ast::Ident)
|
ident: ast::Ident)
|
||||||
-> ast::QPath;
|
-> (ast::QSelf, ast::Path);
|
||||||
fn qpath_all(&self, self_type: P<ast::Ty>,
|
fn qpath_all(&self, self_type: P<ast::Ty>,
|
||||||
trait_path: ast::Path,
|
trait_path: ast::Path,
|
||||||
ident: ast::Ident,
|
ident: ast::Ident,
|
||||||
lifetimes: Vec<ast::Lifetime>,
|
lifetimes: Vec<ast::Lifetime>,
|
||||||
types: Vec<P<ast::Ty>>,
|
types: Vec<P<ast::Ty>>,
|
||||||
bindings: Vec<P<ast::TypeBinding>>)
|
bindings: Vec<P<ast::TypeBinding>>)
|
||||||
-> ast::QPath;
|
-> (ast::QSelf, ast::Path);
|
||||||
|
|
||||||
// types
|
// types
|
||||||
fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
|
fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
|
||||||
|
@ -114,7 +114,7 @@ pub trait AstBuilder {
|
||||||
// expressions
|
// expressions
|
||||||
fn expr(&self, span: Span, node: ast::Expr_) -> P<ast::Expr>;
|
fn expr(&self, span: Span, node: ast::Expr_) -> P<ast::Expr>;
|
||||||
fn expr_path(&self, path: ast::Path) -> P<ast::Expr>;
|
fn expr_path(&self, path: ast::Path) -> P<ast::Expr>;
|
||||||
fn expr_qpath(&self, span: Span, qpath: ast::QPath) -> P<ast::Expr>;
|
fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr>;
|
||||||
fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr>;
|
fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr>;
|
||||||
|
|
||||||
fn expr_self(&self, span: Span) -> P<ast::Expr>;
|
fn expr_self(&self, span: Span) -> P<ast::Expr>;
|
||||||
|
@ -351,7 +351,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
self_type: P<ast::Ty>,
|
self_type: P<ast::Ty>,
|
||||||
trait_path: ast::Path,
|
trait_path: ast::Path,
|
||||||
ident: ast::Ident)
|
ident: ast::Ident)
|
||||||
-> ast::QPath {
|
-> (ast::QSelf, ast::Path) {
|
||||||
self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
|
self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +365,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
lifetimes: Vec<ast::Lifetime>,
|
lifetimes: Vec<ast::Lifetime>,
|
||||||
types: Vec<P<ast::Ty>>,
|
types: Vec<P<ast::Ty>>,
|
||||||
bindings: Vec<P<ast::TypeBinding>>)
|
bindings: Vec<P<ast::TypeBinding>>)
|
||||||
-> ast::QPath {
|
-> (ast::QSelf, ast::Path) {
|
||||||
let mut path = trait_path;
|
let mut path = trait_path;
|
||||||
path.segments.push(ast::PathSegment {
|
path.segments.push(ast::PathSegment {
|
||||||
identifier: ident,
|
identifier: ident,
|
||||||
|
@ -376,10 +376,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
ast::QPath {
|
(ast::QSelf {
|
||||||
self_type: self_type,
|
ty: self_type,
|
||||||
path: path
|
position: path.segments.len() - 1
|
||||||
}
|
}, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
|
fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
|
||||||
|
@ -398,7 +398,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_path(&self, path: ast::Path) -> P<ast::Ty> {
|
fn ty_path(&self, path: ast::Path) -> P<ast::Ty> {
|
||||||
self.ty(path.span, ast::TyPath(path))
|
self.ty(path.span, ast::TyPath(None, path))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_sum(&self, path: ast::Path, bounds: OwnedSlice<ast::TyParamBound>) -> P<ast::Ty> {
|
fn ty_sum(&self, path: ast::Path, bounds: OwnedSlice<ast::TyParamBound>) -> P<ast::Ty> {
|
||||||
|
@ -603,12 +603,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_path(&self, path: ast::Path) -> P<ast::Expr> {
|
fn expr_path(&self, path: ast::Path) -> P<ast::Expr> {
|
||||||
self.expr(path.span, ast::ExprPath(path))
|
self.expr(path.span, ast::ExprPath(None, path))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a QPath expression.
|
/// Constructs a QPath expression.
|
||||||
fn expr_qpath(&self, span: Span, qpath: ast::QPath) -> P<ast::Expr> {
|
fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr> {
|
||||||
self.expr(span, ast::ExprQPath(qpath))
|
self.expr(span, ast::ExprPath(Some(qself), path))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> {
|
fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> {
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
|
||||||
|
|
||||||
let e = P(ast::Expr {
|
let e = P(ast::Expr {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprPath(
|
node: ast::ExprPath(None,
|
||||||
ast::Path {
|
ast::Path {
|
||||||
span: sp,
|
span: sp,
|
||||||
global: false,
|
global: false,
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub fn expand_type(t: P<ast::Ty>,
|
||||||
debug!("expanding type {:?} with impl_ty {:?}", t, impl_ty);
|
debug!("expanding type {:?} with impl_ty {:?}", t, impl_ty);
|
||||||
let t = match (t.node.clone(), impl_ty) {
|
let t = match (t.node.clone(), impl_ty) {
|
||||||
// Expand uses of `Self` in impls to the concrete type.
|
// Expand uses of `Self` in impls to the concrete type.
|
||||||
(ast::Ty_::TyPath(ref path), Some(ref impl_ty)) => {
|
(ast::Ty_::TyPath(None, ref path), Some(ref impl_ty)) => {
|
||||||
let path_as_ident = path_to_ident(path);
|
let path_as_ident = path_to_ident(path);
|
||||||
// Note unhygenic comparison here. I think this is correct, since
|
// Note unhygenic comparison here. I think this is correct, since
|
||||||
// even though `Self` is almost just a type parameter, the treatment
|
// even though `Self` is almost just a type parameter, the treatment
|
||||||
|
@ -1594,13 +1594,10 @@ mod test {
|
||||||
|
|
||||||
impl<'v> Visitor<'v> for PathExprFinderContext {
|
impl<'v> Visitor<'v> for PathExprFinderContext {
|
||||||
fn visit_expr(&mut self, expr: &ast::Expr) {
|
fn visit_expr(&mut self, expr: &ast::Expr) {
|
||||||
match expr.node {
|
if let ast::ExprPath(None, ref p) = expr.node {
|
||||||
ast::ExprPath(ref p) => {
|
self.path_accumulator.push(p.clone());
|
||||||
self.path_accumulator.push(p.clone());
|
|
||||||
// not calling visit_path, but it should be fine.
|
|
||||||
}
|
|
||||||
_ => visit::walk_expr(self, expr)
|
|
||||||
}
|
}
|
||||||
|
visit::walk_expr(self, expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -549,7 +549,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
|
||||||
|
|
||||||
fn visit_ty(&mut self, t: &ast::Ty) {
|
fn visit_ty(&mut self, t: &ast::Ty) {
|
||||||
match t.node {
|
match t.node {
|
||||||
ast::TyPath(ref p) => {
|
ast::TyPath(None, ref p) => {
|
||||||
match &*p.segments {
|
match &*p.segments {
|
||||||
|
|
||||||
[ast::PathSegment { identifier, .. }] => {
|
[ast::PathSegment { identifier, .. }] => {
|
||||||
|
|
|
@ -424,12 +424,14 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
|
||||||
}
|
}
|
||||||
TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
|
TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
|
||||||
TyParen(ty) => TyParen(fld.fold_ty(ty)),
|
TyParen(ty) => TyParen(fld.fold_ty(ty)),
|
||||||
TyPath(path) => TyPath(fld.fold_path(path)),
|
TyPath(qself, path) => {
|
||||||
TyQPath(qpath) => {
|
let qself = qself.map(|QSelf { ty, position }| {
|
||||||
TyQPath(QPath {
|
QSelf {
|
||||||
self_type: fld.fold_ty(qpath.self_type),
|
ty: fld.fold_ty(ty),
|
||||||
path: fld.fold_path(qpath.path)
|
position: position
|
||||||
})
|
}
|
||||||
|
});
|
||||||
|
TyPath(qself, fld.fold_path(path))
|
||||||
}
|
}
|
||||||
TyObjectSum(ty, bounds) => {
|
TyObjectSum(ty, bounds) => {
|
||||||
TyObjectSum(fld.fold_ty(ty),
|
TyObjectSum(fld.fold_ty(ty),
|
||||||
|
@ -1347,11 +1349,15 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
|
||||||
ExprRange(e1.map(|x| folder.fold_expr(x)),
|
ExprRange(e1.map(|x| folder.fold_expr(x)),
|
||||||
e2.map(|x| folder.fold_expr(x)))
|
e2.map(|x| folder.fold_expr(x)))
|
||||||
}
|
}
|
||||||
ExprPath(pth) => ExprPath(folder.fold_path(pth)),
|
ExprPath(qself, path) => {
|
||||||
ExprQPath(qpath) => ExprQPath(QPath {
|
let qself = qself.map(|QSelf { ty, position }| {
|
||||||
self_type: folder.fold_ty(qpath.self_type),
|
QSelf {
|
||||||
path: folder.fold_path(qpath.path)
|
ty: folder.fold_ty(ty),
|
||||||
}),
|
position: position
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ExprPath(qself, folder.fold_path(path))
|
||||||
|
}
|
||||||
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))),
|
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))),
|
||||||
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))),
|
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))),
|
||||||
ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
|
ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
|
||||||
|
|
|
@ -774,7 +774,7 @@ mod test {
|
||||||
assert!(string_to_expr("a".to_string()) ==
|
assert!(string_to_expr("a".to_string()) ==
|
||||||
P(ast::Expr{
|
P(ast::Expr{
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprPath(ast::Path {
|
node: ast::ExprPath(None, ast::Path {
|
||||||
span: sp(0, 1),
|
span: sp(0, 1),
|
||||||
global: false,
|
global: false,
|
||||||
segments: vec!(
|
segments: vec!(
|
||||||
|
@ -792,7 +792,7 @@ mod test {
|
||||||
assert!(string_to_expr("::a::b".to_string()) ==
|
assert!(string_to_expr("::a::b".to_string()) ==
|
||||||
P(ast::Expr {
|
P(ast::Expr {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprPath(ast::Path {
|
node: ast::ExprPath(None, ast::Path {
|
||||||
span: sp(0, 6),
|
span: sp(0, 6),
|
||||||
global: true,
|
global: true,
|
||||||
segments: vec!(
|
segments: vec!(
|
||||||
|
@ -974,7 +974,7 @@ mod test {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node:ast::ExprRet(Some(P(ast::Expr{
|
node:ast::ExprRet(Some(P(ast::Expr{
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node:ast::ExprPath(ast::Path{
|
node:ast::ExprPath(None, ast::Path{
|
||||||
span: sp(7, 8),
|
span: sp(7, 8),
|
||||||
global: false,
|
global: false,
|
||||||
segments: vec!(
|
segments: vec!(
|
||||||
|
@ -995,7 +995,7 @@ mod test {
|
||||||
P(Spanned{
|
P(Spanned{
|
||||||
node: ast::StmtExpr(P(ast::Expr {
|
node: ast::StmtExpr(P(ast::Expr {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprPath(ast::Path {
|
node: ast::ExprPath(None, ast::Path {
|
||||||
span:sp(0,1),
|
span:sp(0,1),
|
||||||
global:false,
|
global:false,
|
||||||
segments: vec!(
|
segments: vec!(
|
||||||
|
@ -1041,7 +1041,7 @@ mod test {
|
||||||
node: ast::ItemFn(P(ast::FnDecl {
|
node: ast::ItemFn(P(ast::FnDecl {
|
||||||
inputs: vec!(ast::Arg{
|
inputs: vec!(ast::Arg{
|
||||||
ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
|
ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::TyPath(ast::Path{
|
node: ast::TyPath(None, ast::Path{
|
||||||
span:sp(10,13),
|
span:sp(10,13),
|
||||||
global:false,
|
global:false,
|
||||||
segments: vec!(
|
segments: vec!(
|
||||||
|
@ -1084,7 +1084,7 @@ mod test {
|
||||||
stmts: vec!(P(Spanned{
|
stmts: vec!(P(Spanned{
|
||||||
node: ast::StmtSemi(P(ast::Expr{
|
node: ast::StmtSemi(P(ast::Expr{
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: ast::ExprPath(
|
node: ast::ExprPath(None,
|
||||||
ast::Path{
|
ast::Path{
|
||||||
span:sp(17,18),
|
span:sp(17,18),
|
||||||
global:false,
|
global:false,
|
||||||
|
|
|
@ -25,7 +25,7 @@ use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
|
||||||
use ast::{ExprBreak, ExprCall, ExprCast};
|
use ast::{ExprBreak, ExprCall, ExprCast};
|
||||||
use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex};
|
use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex};
|
||||||
use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
|
use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
|
||||||
use ast::{ExprMethodCall, ExprParen, ExprPath, ExprQPath};
|
use ast::{ExprMethodCall, ExprParen, ExprPath};
|
||||||
use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
|
use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
|
||||||
use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
|
use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
|
||||||
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
|
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
|
||||||
|
@ -43,7 +43,7 @@ use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot};
|
||||||
use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
|
use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
|
||||||
use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
|
use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
|
||||||
use ast::{PolyTraitRef};
|
use ast::{PolyTraitRef};
|
||||||
use ast::{QPath, RequiredMethod};
|
use ast::{QSelf, RequiredMethod};
|
||||||
use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
|
use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
|
||||||
use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
|
use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
|
||||||
use ast::{StructVariantKind, BiSub, StrStyle};
|
use ast::{StructVariantKind, BiSub, StrStyle};
|
||||||
|
@ -53,7 +53,7 @@ use ast::{TtDelimited, TtSequence, TtToken};
|
||||||
use ast::{TupleVariantKind, Ty, Ty_, TypeBinding};
|
use ast::{TupleVariantKind, Ty, Ty_, TypeBinding};
|
||||||
use ast::{TyFixedLengthVec, TyBareFn};
|
use ast::{TyFixedLengthVec, TyBareFn};
|
||||||
use ast::{TyTypeof, TyInfer, TypeMethod};
|
use ast::{TyTypeof, TyInfer, TypeMethod};
|
||||||
use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath};
|
use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr};
|
||||||
use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
|
use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
|
||||||
use ast::{TypeImplItem, TypeTraitItem, Typedef,};
|
use ast::{TypeImplItem, TypeTraitItem, Typedef,};
|
||||||
use ast::{UnnamedField, UnsafeBlock};
|
use ast::{UnnamedField, UnsafeBlock};
|
||||||
|
@ -143,7 +143,7 @@ macro_rules! maybe_whole_expr {
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
let span = $p.span;
|
let span = $p.span;
|
||||||
Some($p.mk_expr(span.lo, span.hi, ExprPath(pt)))
|
Some($p.mk_expr(span.lo, span.hi, ExprPath(None, pt)))
|
||||||
}
|
}
|
||||||
token::Interpolated(token::NtBlock(_)) => {
|
token::Interpolated(token::NtBlock(_)) => {
|
||||||
// FIXME: The following avoids an issue with lexical borrowck scopes,
|
// FIXME: The following avoids an issue with lexical borrowck scopes,
|
||||||
|
@ -1076,7 +1076,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_ty_path(&mut self) -> Ty_ {
|
pub fn parse_ty_path(&mut self) -> Ty_ {
|
||||||
TyPath(self.parse_path(LifetimeAndTypesWithoutColons))
|
TyPath(None, self.parse_path(LifetimeAndTypesWithoutColons))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// parse a TyBareFn type:
|
/// parse a TyBareFn type:
|
||||||
|
@ -1524,15 +1524,36 @@ impl<'a> Parser<'a> {
|
||||||
} else if self.eat_lt() {
|
} else if self.eat_lt() {
|
||||||
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
|
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
|
||||||
let self_type = self.parse_ty_sum();
|
let self_type = self.parse_ty_sum();
|
||||||
self.expect_keyword(keywords::As);
|
|
||||||
let mut path = self.parse_path(LifetimeAndTypesWithoutColons);
|
let mut path = if self.eat_keyword(keywords::As) {
|
||||||
|
self.parse_path(LifetimeAndTypesWithoutColons)
|
||||||
|
} else {
|
||||||
|
ast::Path {
|
||||||
|
span: self.span,
|
||||||
|
global: false,
|
||||||
|
segments: vec![]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let qself = QSelf {
|
||||||
|
ty: self_type,
|
||||||
|
position: path.segments.len()
|
||||||
|
};
|
||||||
|
|
||||||
self.expect(&token::Gt);
|
self.expect(&token::Gt);
|
||||||
self.expect(&token::ModSep);
|
self.expect(&token::ModSep);
|
||||||
|
|
||||||
path.segments.push(ast::PathSegment {
|
path.segments.push(ast::PathSegment {
|
||||||
identifier: self.parse_ident(),
|
identifier: self.parse_ident(),
|
||||||
parameters: ast::PathParameters::none()
|
parameters: ast::PathParameters::none()
|
||||||
});
|
});
|
||||||
TyQPath(QPath { self_type: self_type, path: path })
|
|
||||||
|
if path.segments.len() == 1 {
|
||||||
|
path.span.lo = self.last_span.lo;
|
||||||
|
}
|
||||||
|
path.span.hi = self.last_span.hi;
|
||||||
|
|
||||||
|
TyPath(Some(qself), path)
|
||||||
} else if self.check(&token::ModSep) ||
|
} else if self.check(&token::ModSep) ||
|
||||||
self.token.is_ident() ||
|
self.token.is_ident() ||
|
||||||
self.token.is_path() {
|
self.token.is_path() {
|
||||||
|
@ -2173,7 +2194,7 @@ impl<'a> Parser<'a> {
|
||||||
}, token::Plain) => {
|
}, token::Plain) => {
|
||||||
self.bump();
|
self.bump();
|
||||||
let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
|
let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
|
||||||
ex = ExprPath(path);
|
ex = ExprPath(None, path);
|
||||||
hi = self.last_span.hi;
|
hi = self.last_span.hi;
|
||||||
}
|
}
|
||||||
token::OpenDelim(token::Bracket) => {
|
token::OpenDelim(token::Bracket) => {
|
||||||
|
@ -2215,10 +2236,22 @@ impl<'a> Parser<'a> {
|
||||||
if self.eat_lt() {
|
if self.eat_lt() {
|
||||||
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item::<'a, T>`
|
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item::<'a, T>`
|
||||||
let self_type = self.parse_ty_sum();
|
let self_type = self.parse_ty_sum();
|
||||||
self.expect_keyword(keywords::As);
|
let mut path = if self.eat_keyword(keywords::As) {
|
||||||
let mut path = self.parse_path(LifetimeAndTypesWithoutColons);
|
self.parse_path(LifetimeAndTypesWithoutColons)
|
||||||
|
} else {
|
||||||
|
ast::Path {
|
||||||
|
span: self.span,
|
||||||
|
global: false,
|
||||||
|
segments: vec![]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let qself = QSelf {
|
||||||
|
ty: self_type,
|
||||||
|
position: path.segments.len()
|
||||||
|
};
|
||||||
self.expect(&token::Gt);
|
self.expect(&token::Gt);
|
||||||
self.expect(&token::ModSep);
|
self.expect(&token::ModSep);
|
||||||
|
|
||||||
let item_name = self.parse_ident();
|
let item_name = self.parse_ident();
|
||||||
let parameters = if self.eat(&token::ModSep) {
|
let parameters = if self.eat(&token::ModSep) {
|
||||||
self.expect_lt();
|
self.expect_lt();
|
||||||
|
@ -2237,9 +2270,14 @@ impl<'a> Parser<'a> {
|
||||||
identifier: item_name,
|
identifier: item_name,
|
||||||
parameters: parameters
|
parameters: parameters
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if path.segments.len() == 1 {
|
||||||
|
path.span.lo = self.last_span.lo;
|
||||||
|
}
|
||||||
|
path.span.hi = self.last_span.hi;
|
||||||
|
|
||||||
let hi = self.span.hi;
|
let hi = self.span.hi;
|
||||||
return self.mk_expr(lo, hi,
|
return self.mk_expr(lo, hi, ExprPath(Some(qself), path));
|
||||||
ExprQPath(QPath { self_type: self_type, path: path }));
|
|
||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Move) {
|
if self.eat_keyword(keywords::Move) {
|
||||||
return self.parse_lambda_expr(CaptureByValue);
|
return self.parse_lambda_expr(CaptureByValue);
|
||||||
|
@ -2379,7 +2417,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hi = pth.span.hi;
|
hi = pth.span.hi;
|
||||||
ex = ExprPath(pth);
|
ex = ExprPath(None, pth);
|
||||||
} else {
|
} else {
|
||||||
// other literal expression
|
// other literal expression
|
||||||
let lit = self.parse_lit();
|
let lit = self.parse_lit();
|
||||||
|
@ -3421,7 +3459,7 @@ impl<'a> Parser<'a> {
|
||||||
let end = if self.token.is_ident() || self.token.is_path() {
|
let end = if self.token.is_ident() || self.token.is_path() {
|
||||||
let path = self.parse_path(LifetimeAndTypesWithColons);
|
let path = self.parse_path(LifetimeAndTypesWithColons);
|
||||||
let hi = self.span.hi;
|
let hi = self.span.hi;
|
||||||
self.mk_expr(lo, hi, ExprPath(path))
|
self.mk_expr(lo, hi, ExprPath(None, path))
|
||||||
} else {
|
} else {
|
||||||
self.parse_literal_maybe_minus()
|
self.parse_literal_maybe_minus()
|
||||||
};
|
};
|
||||||
|
@ -4808,7 +4846,7 @@ impl<'a> Parser<'a> {
|
||||||
let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
|
let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
|
||||||
// New-style trait. Reinterpret the type as a trait.
|
// New-style trait. Reinterpret the type as a trait.
|
||||||
match ty.node {
|
match ty.node {
|
||||||
TyPath(ref path) => {
|
TyPath(None, ref path) => {
|
||||||
Some(TraitRef {
|
Some(TraitRef {
|
||||||
path: (*path).clone(),
|
path: (*path).clone(),
|
||||||
ref_id: ty.id,
|
ref_id: ty.id,
|
||||||
|
|
|
@ -729,11 +729,11 @@ impl<'a> State<'a> {
|
||||||
&generics,
|
&generics,
|
||||||
None));
|
None));
|
||||||
}
|
}
|
||||||
ast::TyPath(ref path) => {
|
ast::TyPath(None, ref path) => {
|
||||||
try!(self.print_path(path, false, 0));
|
try!(self.print_path(path, false, 0));
|
||||||
}
|
}
|
||||||
ast::TyQPath(ref qpath) => {
|
ast::TyPath(Some(ref qself), ref path) => {
|
||||||
try!(self.print_qpath(qpath, false))
|
try!(self.print_qpath(path, qself, false))
|
||||||
}
|
}
|
||||||
ast::TyObjectSum(ref ty, ref bounds) => {
|
ast::TyObjectSum(ref ty, ref bounds) => {
|
||||||
try!(self.print_type(&**ty));
|
try!(self.print_type(&**ty));
|
||||||
|
@ -1852,8 +1852,12 @@ impl<'a> State<'a> {
|
||||||
try!(self.print_expr(&**e));
|
try!(self.print_expr(&**e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprPath(ref path) => try!(self.print_path(path, true, 0)),
|
ast::ExprPath(None, ref path) => {
|
||||||
ast::ExprQPath(ref qpath) => try!(self.print_qpath(qpath, true)),
|
try!(self.print_path(path, true, 0))
|
||||||
|
}
|
||||||
|
ast::ExprPath(Some(ref qself), ref path) => {
|
||||||
|
try!(self.print_qpath(path, qself, true))
|
||||||
|
}
|
||||||
ast::ExprBreak(opt_ident) => {
|
ast::ExprBreak(opt_ident) => {
|
||||||
try!(word(&mut self.s, "break"));
|
try!(word(&mut self.s, "break"));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
|
@ -2037,18 +2041,19 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_qpath(&mut self,
|
fn print_qpath(&mut self,
|
||||||
qpath: &ast::QPath,
|
path: &ast::Path,
|
||||||
|
qself: &ast::QSelf,
|
||||||
colons_before_params: bool)
|
colons_before_params: bool)
|
||||||
-> IoResult<()>
|
-> IoResult<()>
|
||||||
{
|
{
|
||||||
try!(word(&mut self.s, "<"));
|
try!(word(&mut self.s, "<"));
|
||||||
try!(self.print_type(&*qpath.self_type));
|
try!(self.print_type(&qself.ty));
|
||||||
try!(space(&mut self.s));
|
try!(space(&mut self.s));
|
||||||
try!(self.word_space("as"));
|
try!(self.word_space("as"));
|
||||||
try!(self.print_path(&qpath.path, false, 1));
|
try!(self.print_path(&path, false, 1));
|
||||||
try!(word(&mut self.s, ">"));
|
try!(word(&mut self.s, ">"));
|
||||||
try!(word(&mut self.s, "::"));
|
try!(word(&mut self.s, "::"));
|
||||||
let item_segment = qpath.path.segments.last().unwrap();
|
let item_segment = path.segments.last().unwrap();
|
||||||
try!(self.print_ident(item_segment.identifier));
|
try!(self.print_ident(item_segment.identifier));
|
||||||
self.print_path_parameters(&item_segment.parameters, colons_before_params)
|
self.print_path_parameters(&item_segment.parameters, colons_before_params)
|
||||||
}
|
}
|
||||||
|
|
|
@ -396,13 +396,12 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
||||||
walk_fn_ret_ty(visitor, &function_declaration.decl.output);
|
walk_fn_ret_ty(visitor, &function_declaration.decl.output);
|
||||||
walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
|
walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
|
||||||
}
|
}
|
||||||
TyPath(ref path) => {
|
TyPath(ref maybe_qself, ref path) => {
|
||||||
|
if let Some(ref qself) = *maybe_qself {
|
||||||
|
visitor.visit_ty(&qself.ty);
|
||||||
|
}
|
||||||
visitor.visit_path(path, typ.id);
|
visitor.visit_path(path, typ.id);
|
||||||
}
|
}
|
||||||
TyQPath(ref qpath) => {
|
|
||||||
visitor.visit_ty(&*qpath.self_type);
|
|
||||||
visitor.visit_path(&qpath.path, typ.id);
|
|
||||||
}
|
|
||||||
TyObjectSum(ref ty, ref bounds) => {
|
TyObjectSum(ref ty, ref bounds) => {
|
||||||
visitor.visit_ty(&**ty);
|
visitor.visit_ty(&**ty);
|
||||||
walk_ty_param_bounds_helper(visitor, bounds);
|
walk_ty_param_bounds_helper(visitor, bounds);
|
||||||
|
@ -859,13 +858,12 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
||||||
walk_expr_opt(visitor, start);
|
walk_expr_opt(visitor, start);
|
||||||
walk_expr_opt(visitor, end)
|
walk_expr_opt(visitor, end)
|
||||||
}
|
}
|
||||||
ExprPath(ref path) => {
|
ExprPath(ref maybe_qself, ref path) => {
|
||||||
|
if let Some(ref qself) = *maybe_qself {
|
||||||
|
visitor.visit_ty(&qself.ty);
|
||||||
|
}
|
||||||
visitor.visit_path(path, expression.id)
|
visitor.visit_path(path, expression.id)
|
||||||
}
|
}
|
||||||
ExprQPath(ref qpath) => {
|
|
||||||
visitor.visit_ty(&*qpath.self_type);
|
|
||||||
visitor.visit_path(&qpath.path, expression.id);
|
|
||||||
}
|
|
||||||
ExprBreak(_) | ExprAgain(_) => {}
|
ExprBreak(_) | ExprAgain(_) => {}
|
||||||
ExprRet(ref optional_expression) => {
|
ExprRet(ref optional_expression) => {
|
||||||
walk_expr_opt(visitor, optional_expression)
|
walk_expr_opt(visitor, optional_expression)
|
||||||
|
|
|
@ -61,8 +61,10 @@ tests! {
|
||||||
// Inherent static methods.
|
// Inherent static methods.
|
||||||
Vec::new, fn() -> Vec<()>, ();
|
Vec::new, fn() -> Vec<()>, ();
|
||||||
Vec::<()>::new, fn() -> Vec<()>, ();
|
Vec::<()>::new, fn() -> Vec<()>, ();
|
||||||
|
<Vec<()>>::new, fn() -> Vec<()>, ();
|
||||||
Vec::with_capacity, fn(usize) -> Vec<()>, (5);
|
Vec::with_capacity, fn(usize) -> Vec<()>, (5);
|
||||||
Vec::<()>::with_capacity, fn(usize) -> Vec<()>, (5);
|
Vec::<()>::with_capacity, fn(usize) -> Vec<()>, (5);
|
||||||
|
<Vec<()>>::with_capacity, fn(usize) -> Vec<()>, (5);
|
||||||
BitVec::from_fn, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd);
|
BitVec::from_fn, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd);
|
||||||
BitVec::from_fn::<fn(usize) -> bool>, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd);
|
BitVec::from_fn::<fn(usize) -> bool>, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd);
|
||||||
|
|
||||||
|
@ -78,26 +80,32 @@ tests! {
|
||||||
|
|
||||||
// Trait static methods.
|
// Trait static methods.
|
||||||
bool::size, fn() -> usize, ();
|
bool::size, fn() -> usize, ();
|
||||||
|
<bool>::size, fn() -> usize, ();
|
||||||
<bool as Size>::size, fn() -> usize, ();
|
<bool as Size>::size, fn() -> usize, ();
|
||||||
|
|
||||||
Default::default, fn() -> i32, ();
|
Default::default, fn() -> i32, ();
|
||||||
i32::default, fn() -> i32, ();
|
i32::default, fn() -> i32, ();
|
||||||
|
<i32>::default, fn() -> i32, ();
|
||||||
<i32 as Default>::default, fn() -> i32, ();
|
<i32 as Default>::default, fn() -> i32, ();
|
||||||
|
|
||||||
Rand::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
Rand::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
||||||
i32::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
i32::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
||||||
|
<i32>::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
||||||
<i32 as Rand>::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
<i32 as Rand>::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
||||||
Rand::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
Rand::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
||||||
i32::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
i32::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
||||||
|
<i32>::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
||||||
<i32 as Rand>::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
<i32 as Rand>::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
|
||||||
|
|
||||||
// Trait non-static methods.
|
// Trait non-static methods.
|
||||||
Clone::clone, fn(&i32) -> i32, (&5);
|
Clone::clone, fn(&i32) -> i32, (&5);
|
||||||
i32::clone, fn(&i32) -> i32, (&5);
|
i32::clone, fn(&i32) -> i32, (&5);
|
||||||
|
<i32>::clone, fn(&i32) -> i32, (&5);
|
||||||
<i32 as Clone>::clone, fn(&i32) -> i32, (&5);
|
<i32 as Clone>::clone, fn(&i32) -> i32, (&5);
|
||||||
|
|
||||||
FromIterator::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
|
FromIterator::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
|
||||||
Vec::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
|
Vec::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
|
||||||
|
<Vec<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
|
||||||
<Vec<_> as FromIterator<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>,
|
<Vec<_> as FromIterator<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>,
|
||||||
(Some(5).into_iter());
|
(Some(5).into_iter());
|
||||||
<Vec<i32> as FromIterator<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>,
|
<Vec<i32> as FromIterator<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>,
|
||||||
|
@ -109,11 +117,14 @@ tests! {
|
||||||
|
|
||||||
Add::add, fn(i32, i32) -> i32, (5, 6);
|
Add::add, fn(i32, i32) -> i32, (5, 6);
|
||||||
i32::add, fn(i32, i32) -> i32, (5, 6);
|
i32::add, fn(i32, i32) -> i32, (5, 6);
|
||||||
|
<i32>::add, fn(i32, i32) -> i32, (5, 6);
|
||||||
<i32 as Add<_>>::add, fn(i32, i32) -> i32, (5, 6);
|
<i32 as Add<_>>::add, fn(i32, i32) -> i32, (5, 6);
|
||||||
<i32 as Add<i32>>::add, fn(i32, i32) -> i32, (5, 6);
|
<i32 as Add<i32>>::add, fn(i32, i32) -> i32, (5, 6);
|
||||||
|
|
||||||
String::into_cow, fn(String) -> Cow<'static, str>,
|
String::into_cow, fn(String) -> Cow<'static, str>,
|
||||||
("foo".to_string());
|
("foo".to_string());
|
||||||
|
<String>::into_cow, fn(String) -> Cow<'static, str>,
|
||||||
|
("foo".to_string());
|
||||||
<String as IntoCow<_>>::into_cow, fn(String) -> Cow<'static, str>,
|
<String as IntoCow<_>>::into_cow, fn(String) -> Cow<'static, str>,
|
||||||
("foo".to_string());
|
("foo".to_string());
|
||||||
<String as IntoCow<'static, _>>::into_cow, fn(String) -> Cow<'static, str>,
|
<String as IntoCow<'static, _>>::into_cow, fn(String) -> Cow<'static, str>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue