1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 source_map::{self, Span},
18 use crate::macros::MacroArg;
19 use crate::utils::{mk_sp, outer_attributes};
21 /// Spanned returns a span including attributes, if available.
23 fn span(&self) -> Span;
26 impl<T: Spanned> Spanned for ptr::P<T> {
27 fn span(&self) -> Span {
32 impl<T> Spanned for source_map::Spanned<T> {
33 fn span(&self) -> Span {
38 macro_rules! span_with_attrs_lo_hi {
39 ($this:ident, $lo:expr, $hi:expr) => {{
40 let attrs = outer_attributes(&$this.attrs);
44 mk_sp(attrs[0].span.lo(), $hi)
49 macro_rules! span_with_attrs {
51 span_with_attrs_lo_hi!($this, $this.span.lo(), $this.span.hi())
55 macro_rules! implement_spanned {
57 impl Spanned for $this {
58 fn span(&self) -> Span {
59 span_with_attrs!(self)
65 // Implement `Spanned` for structs with `attrs` field.
66 implement_spanned!(ast::Expr);
67 implement_spanned!(ast::Field);
68 implement_spanned!(ast::ForeignItem);
69 implement_spanned!(ast::Item);
70 implement_spanned!(ast::Local);
71 implement_spanned!(ast::TraitItem);
72 implement_spanned!(ast::ImplItem);
74 impl Spanned for ast::Stmt {
75 fn span(&self) -> Span {
77 ast::StmtKind::Local(ref local) => mk_sp(local.span().lo(), self.span.hi()),
78 ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()),
79 ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
80 mk_sp(expr.span().lo(), self.span.hi())
82 ast::StmtKind::Mac(ref mac) => {
83 let (_, _, ref attrs) = **mac;
87 mk_sp(attrs[0].span.lo(), self.span.hi())
94 impl Spanned for ast::Pat {
95 fn span(&self) -> Span {
100 impl Spanned for ast::Ty {
101 fn span(&self) -> Span {
106 impl Spanned for ast::Arm {
107 fn span(&self) -> Span {
108 let lo = if self.attrs.is_empty() {
109 self.pats[0].span.lo()
111 self.attrs[0].span.lo()
113 span_with_attrs_lo_hi!(self, lo, self.body.span.hi())
117 impl Spanned for ast::Arg {
118 fn span(&self) -> Span {
119 if crate::items::is_named_arg(self) {
120 mk_sp(self.pat.span.lo(), self.ty.span.hi())
127 impl Spanned for ast::GenericParam {
128 fn span(&self) -> Span {
129 let lo = if self.attrs.is_empty() {
132 self.attrs[0].span.lo()
134 let hi = if self.bounds.is_empty() {
137 self.bounds.last().unwrap().span().hi()
139 let ty_hi = if let ast::GenericParamKind::Type {
140 default: Some(ref ty),
147 mk_sp(lo, max(hi, ty_hi))
151 impl Spanned for ast::StructField {
152 fn span(&self) -> Span {
153 span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi())
157 impl Spanned for ast::WherePredicate {
158 fn span(&self) -> Span {
160 ast::WherePredicate::BoundPredicate(ref p) => p.span,
161 ast::WherePredicate::RegionPredicate(ref p) => p.span,
162 ast::WherePredicate::EqPredicate(ref p) => p.span,
167 impl Spanned for ast::FunctionRetTy {
168 fn span(&self) -> Span {
170 ast::FunctionRetTy::Default(span) => span,
171 ast::FunctionRetTy::Ty(ref ty) => ty.span,
176 impl Spanned for ast::GenericArg {
177 fn span(&self) -> Span {
179 ast::GenericArg::Lifetime(ref lt) => lt.ident.span,
180 ast::GenericArg::Type(ref ty) => ty.span(),
185 impl Spanned for ast::GenericBound {
186 fn span(&self) -> Span {
188 ast::GenericBound::Trait(ref ptr, _) => ptr.span,
189 ast::GenericBound::Outlives(ref l) => l.ident.span,
194 impl Spanned for MacroArg {
195 fn span(&self) -> Span {
197 MacroArg::Expr(ref expr) => expr.span(),
198 MacroArg::Ty(ref ty) => ty.span(),
199 MacroArg::Pat(ref pat) => pat.span(),
200 MacroArg::Item(ref item) => item.span(),