Skip to content

Commit

Permalink
add Span information into Qself
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed May 22, 2018
1 parent d034ae5 commit e9e8514
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 10 deletions.
21 changes: 21 additions & 0 deletions src/librustc_resolve/lib.rs
Expand Up @@ -3139,6 +3139,17 @@ impl<'a> Resolver<'a> {
span: Span,
global_by_default: bool)
-> Option<PathResolution> {
debug!(
"resolve_qpath(id={:?}, qself={:?}, path={:?}, \
ns={:?}, span={:?}, global_by_default={:?})",
id,
qself,
path,
ns,
span,
global_by_default,
);

if let Some(qself) = qself {
if qself.position == 0 {
// FIXME: Create some fake resolution that can't possibly be a type.
Expand Down Expand Up @@ -3231,6 +3242,15 @@ impl<'a> Resolver<'a> {
let mut allow_super = true;
let mut second_binding = None;

debug!(
"resolve_path(path={:?}, opt_ns={:?}, record_used={:?}, path_span={:?}, crate_lint={:?})",
path,
opt_ns,
record_used,
path_span,
crate_lint,
);

for (i, &ident) in path.iter().enumerate() {
debug!("resolve_path ident {} {:?}", i, ident);
let is_last = i == path.len() - 1;
Expand Down Expand Up @@ -4454,6 +4474,7 @@ pub enum MakeGlobMap {
No,
}

#[derive(Debug)]
enum CrateLint {
/// Do not issue the lint
No,
Expand Down
5 changes: 5 additions & 0 deletions src/libsyntax/ast.rs
Expand Up @@ -1211,6 +1211,11 @@ pub enum ExprKind {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct QSelf {
pub ty: P<Ty>,

/// The span of `a::b::Trait` in a path like `<Vec<T> as
/// a::b::Trait>::AssociatedItem`; in the case where `position ==
/// 0`, this is an empty span.
pub path_span: Span,
pub position: usize
}

Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/ext/build.rs
Expand Up @@ -373,6 +373,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {

(ast::QSelf {
ty: self_type,
path_span: path.span,
position: path.segments.len() - 1
}, path)
}
Expand Down
12 changes: 9 additions & 3 deletions src/libsyntax/fold.rs
Expand Up @@ -390,9 +390,10 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
TyKind::Tup(tys) => TyKind::Tup(tys.move_map(|ty| fld.fold_ty(ty))),
TyKind::Paren(ty) => TyKind::Paren(fld.fold_ty(ty)),
TyKind::Path(qself, path) => {
let qself = qself.map(|QSelf { ty, position }| {
let qself = qself.map(|QSelf { ty, path_span, position }| {
QSelf {
ty: fld.fold_ty(ty),
path_span: fld.new_span(path_span),
position,
}
});
Expand Down Expand Up @@ -1131,7 +1132,11 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
}
PatKind::Path(opt_qself, pth) => {
let opt_qself = opt_qself.map(|qself| {
QSelf { ty: folder.fold_ty(qself.ty), position: qself.position }
QSelf {
ty: folder.fold_ty(qself.ty),
path_span: folder.new_span(qself.path_span),
position: qself.position,
}
});
PatKind::Path(opt_qself, folder.fold_path(pth))
}
Expand Down Expand Up @@ -1292,9 +1297,10 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
lim)
}
ExprKind::Path(qself, path) => {
let qself = qself.map(|QSelf { ty, position }| {
let qself = qself.map(|QSelf { ty, path_span, position }| {
QSelf {
ty: folder.fold_ty(ty),
path_span: folder.new_span(path_span),
position,
}
});
Expand Down
28 changes: 21 additions & 7 deletions src/libsyntax/parse/parser.rs
Expand Up @@ -1715,8 +1715,11 @@ impl<'a> Parser<'a> {
self.parse_path_segments(&mut segments, T::PATH_STYLE, true)?;

let span = ty.span.to(self.prev_span);
let recovered =
base.to_recovered(Some(QSelf { ty, position: 0 }), ast::Path { segments, span });
let path_span = span.to(span); // use an empty path since `position` == 0
let recovered = base.to_recovered(
Some(QSelf { ty, path_span, position: 0 }),
ast::Path { segments, span },
);

self.diagnostic()
.struct_span_err(span, "missing angle brackets in associated item path")
Expand Down Expand Up @@ -1905,21 +1908,32 @@ impl<'a> Parser<'a> {
/// `qualified_path = <type [as trait_ref]>::path`
///
/// # Examples
/// `<T>::default`
/// `<T as U>::a`
/// `<T as U>::F::a<S>` (without disambiguator)
/// `<T as U>::F::a::<S>` (with disambiguator)
fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, ast::Path)> {
let lo = self.prev_span;
let ty = self.parse_ty()?;
let mut path = if self.eat_keyword(keywords::As) {
self.parse_path(PathStyle::Type)?

// `path` will contain the prefix of the path up to the `>`,
// if any (e.g., `U` in the `<T as U>::*` examples
// above). `path_span` has the span of that path, or an empty
// span in the case of something like `<T>::Bar`.
let (mut path, path_span);
if self.eat_keyword(keywords::As) {
let path_lo = self.span;
path = self.parse_path(PathStyle::Type)?;
path_span = path_lo.to(self.prev_span);
} else {
ast::Path { segments: Vec::new(), span: syntax_pos::DUMMY_SP }
};
path = ast::Path { segments: Vec::new(), span: syntax_pos::DUMMY_SP };
path_span = self.span.to(self.span);
}

self.expect(&token::Gt)?;
self.expect(&token::ModSep)?;

let qself = QSelf { ty, position: path.segments.len() };
let qself = QSelf { ty, path_span, position: path.segments.len() };
self.parse_path_segments(&mut path.segments, style, true)?;

Ok((qself, ast::Path { segments: path.segments, span: lo.to(self.prev_span) }))
Expand Down

0 comments on commit e9e8514

Please sign in to comment.