Rollup merge of #40369 - petrochenkov:segspan, r=eddyb
Give spans to individual path segments in AST And use these spans in path resolution diagnostics. The spans are spans of identifiers in segments, not whole segments. I'm not sure what spans are more useful in general, but identifier spans are a better fit for resolve errors. HIR still doesn't have spans. Fixes https://github.com/rust-lang/rust/pull/38927#discussion_r95336667 https://github.com/rust-lang/rust/pull/38890#issuecomment-271731008 r? @nrc @eddyb
This commit is contained in:
commit
8d1c5700f0
@ -407,7 +407,7 @@ enum PathSource<'a> {
|
||||
// Trait paths in bounds or impls.
|
||||
Trait,
|
||||
// Expression paths `path`, with optional parent context.
|
||||
Expr(Option<&'a ExprKind>),
|
||||
Expr(Option<&'a Expr>),
|
||||
// Paths in path patterns `Path`.
|
||||
Pat,
|
||||
// Paths in struct expressions and patterns `Path { .. }`.
|
||||
@ -464,7 +464,7 @@ impl<'a> PathSource<'a> {
|
||||
ValueNS => "method or associated constant",
|
||||
MacroNS => bug!("associated macro"),
|
||||
},
|
||||
PathSource::Expr(parent) => match parent {
|
||||
PathSource::Expr(parent) => match parent.map(|p| &p.node) {
|
||||
// "function" here means "anything callable" rather than `Def::Fn`,
|
||||
// this is not precise but usually more helpful than just "value".
|
||||
Some(&ExprKind::Call(..)) => "function",
|
||||
@ -2200,7 +2200,8 @@ impl<'a> Resolver<'a> {
|
||||
source: PathSource)
|
||||
-> PathResolution {
|
||||
let segments = &path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
|
||||
self.smart_resolve_path_fragment(id, qself, segments, path.span, source)
|
||||
let ident_span = path.segments.last().map_or(path.span, |seg| seg.span);
|
||||
self.smart_resolve_path_fragment(id, qself, segments, path.span, ident_span, source)
|
||||
}
|
||||
|
||||
fn smart_resolve_path_fragment(&mut self,
|
||||
@ -2208,6 +2209,7 @@ impl<'a> Resolver<'a> {
|
||||
qself: Option<&QSelf>,
|
||||
path: &[Ident],
|
||||
span: Span,
|
||||
ident_span: Span,
|
||||
source: PathSource)
|
||||
-> PathResolution {
|
||||
let ns = source.namespace();
|
||||
@ -2219,9 +2221,9 @@ impl<'a> Resolver<'a> {
|
||||
let expected = source.descr_expected();
|
||||
let path_str = names_to_string(path);
|
||||
let code = source.error_code(def.is_some());
|
||||
let (base_msg, fallback_label) = if let Some(def) = def {
|
||||
let (base_msg, fallback_label, base_span) = if let Some(def) = def {
|
||||
(format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
|
||||
format!("not a {}", expected))
|
||||
format!("not a {}", expected), span)
|
||||
} else {
|
||||
let item_str = path[path.len() - 1];
|
||||
let (mod_prefix, mod_str) = if path.len() == 1 {
|
||||
@ -2237,9 +2239,9 @@ impl<'a> Resolver<'a> {
|
||||
(mod_prefix, format!("`{}`", names_to_string(mod_path)))
|
||||
};
|
||||
(format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
|
||||
format!("not found in {}", mod_str))
|
||||
format!("not found in {}", mod_str), ident_span)
|
||||
};
|
||||
let mut err = this.session.struct_span_err_with_code(span, &base_msg, code);
|
||||
let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
|
||||
|
||||
// Emit special messages for unresolved `Self` and `self`.
|
||||
if is_self_type(path, ns) {
|
||||
@ -2297,15 +2299,15 @@ impl<'a> Resolver<'a> {
|
||||
err.span_label(span, &format!("type aliases cannot be used for traits"));
|
||||
return err;
|
||||
}
|
||||
(Def::Mod(..), PathSource::Expr(Some(parent))) => match *parent {
|
||||
(Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {
|
||||
ExprKind::Field(_, ident) => {
|
||||
err.span_label(span, &format!("did you mean `{}::{}`?",
|
||||
path_str, ident.node));
|
||||
err.span_label(parent.span, &format!("did you mean `{}::{}`?",
|
||||
path_str, ident.node));
|
||||
return err;
|
||||
}
|
||||
ExprKind::MethodCall(ident, ..) => {
|
||||
err.span_label(span, &format!("did you mean `{}::{}(...)`?",
|
||||
path_str, ident.node));
|
||||
err.span_label(parent.span, &format!("did you mean `{}::{}(...)`?",
|
||||
path_str, ident.node));
|
||||
return err;
|
||||
}
|
||||
_ => {}
|
||||
@ -2330,12 +2332,12 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// Try Levenshtein if nothing else worked.
|
||||
if let Some(candidate) = this.lookup_typo_candidate(path, ns, is_expected) {
|
||||
err.span_label(span, &format!("did you mean `{}`?", candidate));
|
||||
err.span_label(ident_span, &format!("did you mean `{}`?", candidate));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Fallback label.
|
||||
err.span_label(span, &fallback_label);
|
||||
err.span_label(base_span, &fallback_label);
|
||||
err
|
||||
};
|
||||
let report_errors = |this: &mut Self, def: Option<Def>| {
|
||||
@ -2455,7 +2457,7 @@ impl<'a> Resolver<'a> {
|
||||
// Make sure `A::B` in `<T as A>::B::C` is a trait item.
|
||||
let ns = if qself.position + 1 == path.len() { ns } else { TypeNS };
|
||||
let res = self.smart_resolve_path_fragment(id, None, &path[..qself.position + 1],
|
||||
span, PathSource::TraitItem(ns));
|
||||
span, span, PathSource::TraitItem(ns));
|
||||
return Some(PathResolution::with_unresolved_segments(
|
||||
res.base_def(), res.unresolved_segments() + path.len() - qself.position - 1
|
||||
));
|
||||
@ -2813,7 +2815,7 @@ impl<'a> Resolver<'a> {
|
||||
path: &[Ident],
|
||||
ns: Namespace,
|
||||
filter_fn: FilterFn)
|
||||
-> Option<String>
|
||||
-> Option<Symbol>
|
||||
where FilterFn: Fn(Def) -> bool
|
||||
{
|
||||
let add_module_candidates = |module: Module, names: &mut Vec<Name>| {
|
||||
@ -2827,7 +2829,7 @@ impl<'a> Resolver<'a> {
|
||||
};
|
||||
|
||||
let mut names = Vec::new();
|
||||
let prefix_str = if path.len() == 1 {
|
||||
if path.len() == 1 {
|
||||
// Search in lexical scope.
|
||||
// Walk backwards up the ribs in scope and collect candidates.
|
||||
for rib in self.ribs[ns].iter().rev() {
|
||||
@ -2861,21 +2863,19 @@ impl<'a> Resolver<'a> {
|
||||
names.push(*name);
|
||||
}
|
||||
}
|
||||
String::new()
|
||||
} else {
|
||||
// Search in module.
|
||||
let mod_path = &path[..path.len() - 1];
|
||||
if let PathResult::Module(module) = self.resolve_path(mod_path, Some(TypeNS), None) {
|
||||
add_module_candidates(module, &mut names);
|
||||
}
|
||||
names_to_string(mod_path) + "::"
|
||||
};
|
||||
}
|
||||
|
||||
let name = path[path.len() - 1].name;
|
||||
// Make sure error reporting is deterministic.
|
||||
names.sort_by_key(|name| name.as_str());
|
||||
match find_best_match_for_name(names.iter(), &name.as_str(), None) {
|
||||
Some(found) if found != name => Some(format!("{}{}", prefix_str, found)),
|
||||
Some(found) if found != name => Some(found),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -2898,7 +2898,7 @@ impl<'a> Resolver<'a> {
|
||||
self.with_resolved_label(label, id, |this| this.visit_block(block));
|
||||
}
|
||||
|
||||
fn resolve_expr(&mut self, expr: &Expr, parent: Option<&ExprKind>) {
|
||||
fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
|
||||
// First, record candidate traits for this expression if it could
|
||||
// result in the invocation of a method call.
|
||||
|
||||
@ -2979,11 +2979,11 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// Equivalent to `visit::walk_expr` + passing some context to children.
|
||||
ExprKind::Field(ref subexpression, _) => {
|
||||
self.resolve_expr(subexpression, Some(&expr.node));
|
||||
self.resolve_expr(subexpression, Some(expr));
|
||||
}
|
||||
ExprKind::MethodCall(_, ref types, ref arguments) => {
|
||||
let mut arguments = arguments.iter();
|
||||
self.resolve_expr(arguments.next().unwrap(), Some(&expr.node));
|
||||
self.resolve_expr(arguments.next().unwrap(), Some(expr));
|
||||
for argument in arguments {
|
||||
self.resolve_expr(argument, None);
|
||||
}
|
||||
@ -2999,7 +2999,7 @@ impl<'a> Resolver<'a> {
|
||||
});
|
||||
}
|
||||
ExprKind::Call(ref callee, ref arguments) => {
|
||||
self.resolve_expr(callee, Some(&expr.node));
|
||||
self.resolve_expr(callee, Some(expr));
|
||||
for argument in arguments {
|
||||
self.resolve_expr(argument, None);
|
||||
}
|
||||
@ -3130,11 +3130,10 @@ impl<'a> Resolver<'a> {
|
||||
if ident.name == lookup_name && ns == namespace {
|
||||
if filter_fn(name_binding.def()) {
|
||||
// create the path
|
||||
let span = name_binding.span;
|
||||
let mut segms = path_segments.clone();
|
||||
segms.push(ident.into());
|
||||
segms.push(ast::PathSegment::from_ident(ident, name_binding.span));
|
||||
let path = Path {
|
||||
span: span,
|
||||
span: name_binding.span,
|
||||
segments: segms,
|
||||
};
|
||||
// the entity is accessible in the following cases:
|
||||
@ -3154,7 +3153,7 @@ impl<'a> Resolver<'a> {
|
||||
if let Some(module) = name_binding.module() {
|
||||
// form the path
|
||||
let mut path_segments = path_segments.clone();
|
||||
path_segments.push(ident.into());
|
||||
path_segments.push(ast::PathSegment::from_ident(ident, name_binding.span));
|
||||
|
||||
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
|
||||
// add the module to the lookup
|
||||
|
@ -111,8 +111,11 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
path.segments[0].identifier.name = keywords::CrateRoot.name();
|
||||
let module = self.0.resolve_crate_var(ident.ctxt);
|
||||
if !module.is_local() {
|
||||
let span = path.segments[0].span;
|
||||
path.segments.insert(1, match module.kind {
|
||||
ModuleKind::Def(_, name) => ast::Ident::with_empty_ctxt(name).into(),
|
||||
ModuleKind::Def(_, name) => ast::PathSegment::from_ident(
|
||||
ast::Ident::with_empty_ctxt(name), span
|
||||
),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
@ -569,7 +572,6 @@ impl<'a> Resolver<'a> {
|
||||
};
|
||||
let ident = Ident::from_str(name);
|
||||
self.lookup_typo_candidate(&vec![ident], MacroNS, is_macro)
|
||||
.as_ref().map(|s| Symbol::intern(s))
|
||||
});
|
||||
|
||||
if let Some(suggestion) = suggestion {
|
||||
|
@ -134,7 +134,7 @@ impl Path {
|
||||
pub fn from_ident(s: Span, identifier: Ident) -> Path {
|
||||
Path {
|
||||
span: s,
|
||||
segments: vec![identifier.into()],
|
||||
segments: vec![PathSegment::from_ident(identifier, s)],
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,6 +159,8 @@ impl Path {
|
||||
pub struct PathSegment {
|
||||
/// The identifier portion of this path segment.
|
||||
pub identifier: Ident,
|
||||
/// Span of the segment identifier.
|
||||
pub span: Span,
|
||||
|
||||
/// Type/lifetime parameters attached to this path. They come in
|
||||
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
|
||||
@ -170,16 +172,14 @@ pub struct PathSegment {
|
||||
pub parameters: Option<P<PathParameters>>,
|
||||
}
|
||||
|
||||
impl From<Ident> for PathSegment {
|
||||
fn from(id: Ident) -> Self {
|
||||
PathSegment { identifier: id, parameters: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl PathSegment {
|
||||
pub fn from_ident(ident: Ident, span: Span) -> Self {
|
||||
PathSegment { identifier: ident, span: span, parameters: None }
|
||||
}
|
||||
pub fn crate_root() -> Self {
|
||||
PathSegment {
|
||||
identifier: keywords::CrateRoot.ident(),
|
||||
span: DUMMY_SP,
|
||||
parameters: None,
|
||||
}
|
||||
}
|
||||
|
@ -38,11 +38,11 @@ pub trait AstBuilder {
|
||||
|
||||
fn qpath(&self, self_type: P<ast::Ty>,
|
||||
trait_path: ast::Path,
|
||||
ident: ast::Ident)
|
||||
ident: ast::SpannedIdent)
|
||||
-> (ast::QSelf, ast::Path);
|
||||
fn qpath_all(&self, self_type: P<ast::Ty>,
|
||||
trait_path: ast::Path,
|
||||
ident: ast::Ident,
|
||||
ident: ast::SpannedIdent,
|
||||
lifetimes: Vec<ast::Lifetime>,
|
||||
types: Vec<P<ast::Ty>>,
|
||||
bindings: Vec<ast::TypeBinding>)
|
||||
@ -323,7 +323,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
segments.push(ast::PathSegment::crate_root());
|
||||
}
|
||||
|
||||
segments.extend(idents.into_iter().map(Into::into));
|
||||
segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, sp)));
|
||||
let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
|
||||
None
|
||||
} else {
|
||||
@ -333,7 +333,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
bindings: bindings,
|
||||
})))
|
||||
};
|
||||
segments.push(ast::PathSegment { identifier: last_identifier, parameters: parameters });
|
||||
segments.push(ast::PathSegment {
|
||||
identifier: last_identifier,
|
||||
span: sp,
|
||||
parameters: parameters
|
||||
});
|
||||
ast::Path {
|
||||
span: sp,
|
||||
segments: segments,
|
||||
@ -346,7 +350,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
fn qpath(&self,
|
||||
self_type: P<ast::Ty>,
|
||||
trait_path: ast::Path,
|
||||
ident: ast::Ident)
|
||||
ident: ast::SpannedIdent)
|
||||
-> (ast::QSelf, ast::Path) {
|
||||
self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
|
||||
}
|
||||
@ -357,7 +361,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
fn qpath_all(&self,
|
||||
self_type: P<ast::Ty>,
|
||||
trait_path: ast::Path,
|
||||
ident: ast::Ident,
|
||||
ident: ast::SpannedIdent,
|
||||
lifetimes: Vec<ast::Lifetime>,
|
||||
types: Vec<P<ast::Ty>>,
|
||||
bindings: Vec<ast::TypeBinding>)
|
||||
@ -369,7 +373,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
bindings: bindings,
|
||||
};
|
||||
path.segments.push(ast::PathSegment {
|
||||
identifier: ident,
|
||||
identifier: ident.node,
|
||||
span: ident.span,
|
||||
parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))),
|
||||
});
|
||||
|
||||
|
@ -434,8 +434,9 @@ pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize {
|
||||
|
||||
pub fn noop_fold_path<T: Folder>(Path { segments, span }: Path, fld: &mut T) -> Path {
|
||||
Path {
|
||||
segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment {
|
||||
segments: segments.move_map(|PathSegment {identifier, span, parameters}| PathSegment {
|
||||
identifier: fld.fold_ident(identifier),
|
||||
span: fld.new_span(span),
|
||||
parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
|
||||
}),
|
||||
span: fld.new_span(span)
|
||||
|
@ -617,13 +617,17 @@ mod tests {
|
||||
Span {lo: BytePos(a), hi: BytePos(b), expn_id: NO_EXPANSION}
|
||||
}
|
||||
|
||||
fn str2seg(s: &str, lo: u32, hi: u32) -> ast::PathSegment {
|
||||
ast::PathSegment::from_ident(Ident::from_str(s), sp(lo, hi))
|
||||
}
|
||||
|
||||
#[test] fn path_exprs_1() {
|
||||
assert!(string_to_expr("a".to_string()) ==
|
||||
P(ast::Expr{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span: sp(0, 1),
|
||||
segments: vec![Ident::from_str("a").into()],
|
||||
segments: vec![str2seg("a", 0, 1)],
|
||||
}),
|
||||
span: sp(0, 1),
|
||||
attrs: ThinVec::new(),
|
||||
@ -637,8 +641,8 @@ mod tests {
|
||||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span: sp(0, 6),
|
||||
segments: vec![ast::PathSegment::crate_root(),
|
||||
Ident::from_str("a").into(),
|
||||
Ident::from_str("b").into()]
|
||||
str2seg("a", 2, 3),
|
||||
str2seg("b", 5, 6)]
|
||||
}),
|
||||
span: sp(0, 6),
|
||||
attrs: ThinVec::new(),
|
||||
@ -744,7 +748,7 @@ mod tests {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node:ast::ExprKind::Path(None, ast::Path{
|
||||
span: sp(7, 8),
|
||||
segments: vec![Ident::from_str("d").into()],
|
||||
segments: vec![str2seg("d", 7, 8)],
|
||||
}),
|
||||
span:sp(7,8),
|
||||
attrs: ThinVec::new(),
|
||||
@ -761,7 +765,7 @@ mod tests {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span:sp(0,1),
|
||||
segments: vec![Ident::from_str("b").into()],
|
||||
segments: vec![str2seg("b", 0, 1)],
|
||||
}),
|
||||
span: sp(0,1),
|
||||
attrs: ThinVec::new()})),
|
||||
@ -802,7 +806,7 @@ mod tests {
|
||||
ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
|
||||
node: ast::TyKind::Path(None, ast::Path{
|
||||
span:sp(10,13),
|
||||
segments: vec![Ident::from_str("i32").into()],
|
||||
segments: vec![str2seg("i32", 10, 13)],
|
||||
}),
|
||||
span:sp(10,13)
|
||||
}),
|
||||
@ -844,7 +848,7 @@ mod tests {
|
||||
node: ast::ExprKind::Path(None,
|
||||
ast::Path{
|
||||
span:sp(17,18),
|
||||
segments: vec![Ident::from_str("b").into()],
|
||||
segments: vec![str2seg("b", 17, 18)],
|
||||
}),
|
||||
span: sp(17,18),
|
||||
attrs: ThinVec::new()})),
|
||||
|
@ -27,7 +27,7 @@ use ast::Local;
|
||||
use ast::MacStmtStyle;
|
||||
use ast::Mac_;
|
||||
use ast::{MutTy, Mutability};
|
||||
use ast::{Pat, PatKind};
|
||||
use ast::{Pat, PatKind, PathSegment};
|
||||
use ast::{PolyTraitRef, QSelf};
|
||||
use ast::{Stmt, StmtKind};
|
||||
use ast::{VariantData, StructField};
|
||||
@ -1811,7 +1811,7 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
|
||||
if is_global {
|
||||
segments.insert(0, ast::PathSegment::crate_root());
|
||||
segments.insert(0, PathSegment::crate_root());
|
||||
}
|
||||
|
||||
// Assemble the span.
|
||||
@ -1829,11 +1829,12 @@ impl<'a> Parser<'a> {
|
||||
/// - `a::b<T,U>::c<V,W>`
|
||||
/// - `a::b<T,U>::c(V) -> W`
|
||||
/// - `a::b<T,U>::c(V)`
|
||||
pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
|
||||
pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<PathSegment>> {
|
||||
let mut segments = Vec::new();
|
||||
loop {
|
||||
// First, parse an identifier.
|
||||
let identifier = self.parse_path_segment_ident()?;
|
||||
let ident_span = self.prev_span;
|
||||
|
||||
if self.check(&token::ModSep) && self.look_ahead(1, |t| *t == token::Lt) {
|
||||
self.bump();
|
||||
@ -1881,7 +1882,11 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
|
||||
// Assemble and push the result.
|
||||
segments.push(ast::PathSegment { identifier: identifier, parameters: parameters });
|
||||
segments.push(PathSegment {
|
||||
identifier: identifier,
|
||||
span: ident_span,
|
||||
parameters: parameters
|
||||
});
|
||||
|
||||
// Continue only if we see a `::`
|
||||
if !self.eat(&token::ModSep) {
|
||||
@ -1892,15 +1897,16 @@ impl<'a> Parser<'a> {
|
||||
|
||||
/// Examples:
|
||||
/// - `a::b::<T,U>::c`
|
||||
pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
|
||||
pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<PathSegment>> {
|
||||
let mut segments = Vec::new();
|
||||
loop {
|
||||
// First, parse an identifier.
|
||||
let identifier = self.parse_path_segment_ident()?;
|
||||
let ident_span = self.prev_span;
|
||||
|
||||
// If we do not see a `::`, stop.
|
||||
if !self.eat(&token::ModSep) {
|
||||
segments.push(identifier.into());
|
||||
segments.push(PathSegment::from_ident(identifier, ident_span));
|
||||
return Ok(segments);
|
||||
}
|
||||
|
||||
@ -1909,8 +1915,9 @@ impl<'a> Parser<'a> {
|
||||
// Consumed `a::b::<`, go look for types
|
||||
let (lifetimes, types, bindings) = self.parse_generic_args()?;
|
||||
self.expect_gt()?;
|
||||
segments.push(ast::PathSegment {
|
||||
segments.push(PathSegment {
|
||||
identifier: identifier,
|
||||
span: ident_span,
|
||||
parameters: ast::AngleBracketedParameterData {
|
||||
lifetimes: lifetimes,
|
||||
types: types,
|
||||
@ -1924,7 +1931,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
} else {
|
||||
// Consumed `a::`, go look for `b`
|
||||
segments.push(identifier.into());
|
||||
segments.push(PathSegment::from_ident(identifier, ident_span));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1932,14 +1939,14 @@ impl<'a> Parser<'a> {
|
||||
/// Examples:
|
||||
/// - `a::b::c`
|
||||
pub fn parse_path_segments_without_types(&mut self)
|
||||
-> PResult<'a, Vec<ast::PathSegment>> {
|
||||
-> PResult<'a, Vec<PathSegment>> {
|
||||
let mut segments = Vec::new();
|
||||
loop {
|
||||
// First, parse an identifier.
|
||||
let identifier = self.parse_path_segment_ident()?;
|
||||
|
||||
// Assemble and push the result.
|
||||
segments.push(identifier.into());
|
||||
segments.push(PathSegment::from_ident(identifier, self.prev_span));
|
||||
|
||||
// If we do not see a `::` or see `::{`/`::*`, stop.
|
||||
if !self.check(&token::ModSep) || self.is_import_coupler() {
|
||||
@ -5950,7 +5957,7 @@ impl<'a> Parser<'a> {
|
||||
// `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`.
|
||||
self.eat(&token::ModSep);
|
||||
let prefix = ast::Path {
|
||||
segments: vec![ast::PathSegment::crate_root()],
|
||||
segments: vec![PathSegment::crate_root()],
|
||||
span: mk_sp(lo, self.span.hi),
|
||||
};
|
||||
let view_path_kind = if self.eat(&token::BinOp(token::Star)) {
|
||||
|
@ -82,7 +82,7 @@ pub fn maybe_inject_crates_ref(sess: &ParseSess,
|
||||
vis: ast::Visibility::Inherited,
|
||||
node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path {
|
||||
segments: ["{{root}}", name, "prelude", "v1"].into_iter().map(|name| {
|
||||
ast::Ident::from_str(name).into()
|
||||
ast::PathSegment::from_ident(ast::Ident::from_str(name), DUMMY_SP)
|
||||
}).collect(),
|
||||
span: span,
|
||||
})))),
|
||||
|
@ -580,7 +580,7 @@ fn nospan<T>(t: T) -> codemap::Spanned<T> {
|
||||
fn path_node(ids: Vec<Ident>) -> ast::Path {
|
||||
ast::Path {
|
||||
span: DUMMY_SP,
|
||||
segments: ids.into_iter().map(Into::into).collect(),
|
||||
segments: ids.into_iter().map(|id| ast::PathSegment::from_ident(id, DUMMY_SP)).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
|
||||
fn path(&self) -> ast::Path {
|
||||
ast::Path {
|
||||
span: self.span,
|
||||
segments: vec![self.ident.into()],
|
||||
segments: vec![ast::PathSegment::from_ident(self.ident, self.span)],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,26 @@
|
||||
error[E0425]: cannot find value `A` in module `namespaced_enums`
|
||||
--> $DIR/enums-are-namespaced-xc.rs:15:13
|
||||
--> $DIR/enums-are-namespaced-xc.rs:15:31
|
||||
|
|
||||
15 | let _ = namespaced_enums::A;
|
||||
| ^^^^^^^^^^^^^^^^^^^ not found in `namespaced_enums`
|
||||
| ^ not found in `namespaced_enums`
|
||||
|
|
||||
= help: possible candidate is found in another module, you can import it into scope:
|
||||
`use namespaced_enums::Foo::A;`
|
||||
|
||||
error[E0425]: cannot find function `B` in module `namespaced_enums`
|
||||
--> $DIR/enums-are-namespaced-xc.rs:18:13
|
||||
--> $DIR/enums-are-namespaced-xc.rs:18:31
|
||||
|
|
||||
18 | let _ = namespaced_enums::B(10);
|
||||
| ^^^^^^^^^^^^^^^^^^^ not found in `namespaced_enums`
|
||||
| ^ not found in `namespaced_enums`
|
||||
|
|
||||
= help: possible candidate is found in another module, you can import it into scope:
|
||||
`use namespaced_enums::Foo::B;`
|
||||
|
||||
error[E0422]: cannot find struct, variant or union type `C` in module `namespaced_enums`
|
||||
--> $DIR/enums-are-namespaced-xc.rs:21:13
|
||||
--> $DIR/enums-are-namespaced-xc.rs:21:31
|
||||
|
|
||||
21 | let _ = namespaced_enums::C { a: 10 };
|
||||
| ^^^^^^^^^^^^^^^^^^^ not found in `namespaced_enums`
|
||||
| ^ not found in `namespaced_enums`
|
||||
|
|
||||
= help: possible candidate is found in another module, you can import it into scope:
|
||||
`use namespaced_enums::Foo::C;`
|
||||
|
@ -14,7 +14,7 @@ error[E0412]: cannot find type `Opiton` in this scope
|
||||
--> $DIR/levenshtein.rs:20:10
|
||||
|
|
||||
20 | type B = Opiton<u8>; // Misspelled type name from the prelude.
|
||||
| ^^^^^^^^^^ did you mean `Option`?
|
||||
| ^^^^^^ did you mean `Option`?
|
||||
|
||||
error[E0412]: cannot find type `Baz` in this scope
|
||||
--> $DIR/levenshtein.rs:23:14
|
||||
@ -35,16 +35,16 @@ error[E0425]: cannot find function `foobar` in this scope
|
||||
| ^^^^^^ did you mean `foo_bar`?
|
||||
|
||||
error[E0412]: cannot find type `first` in module `m`
|
||||
--> $DIR/levenshtein.rs:32:12
|
||||
--> $DIR/levenshtein.rs:32:15
|
||||
|
|
||||
32 | let b: m::first = m::second; // Misspelled item in module.
|
||||
| ^^^^^^^^ did you mean `m::First`?
|
||||
| ^^^^^ did you mean `First`?
|
||||
|
||||
error[E0425]: cannot find value `second` in module `m`
|
||||
--> $DIR/levenshtein.rs:32:23
|
||||
--> $DIR/levenshtein.rs:32:26
|
||||
|
|
||||
32 | let b: m::first = m::second; // Misspelled item in module.
|
||||
| ^^^^^^^^^ did you mean `m::Second`?
|
||||
| ^^^^^^ did you mean `Second`?
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
@ -2,55 +2,73 @@ error[E0423]: expected value, found module `a`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:27:5
|
||||
|
|
||||
27 | a.I
|
||||
| ^ did you mean `a::I`?
|
||||
| ^--
|
||||
| |
|
||||
| did you mean `a::I`?
|
||||
|
||||
error[E0423]: expected value, found module `a`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:33:5
|
||||
|
|
||||
33 | a.g()
|
||||
| ^ did you mean `a::g(...)`?
|
||||
| ^----
|
||||
| |
|
||||
| did you mean `a::g(...)`?
|
||||
|
||||
error[E0423]: expected value, found module `a`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:39:5
|
||||
|
|
||||
39 | a.b.J
|
||||
| ^ did you mean `a::b`?
|
||||
| ^--
|
||||
| |
|
||||
| did you mean `a::b`?
|
||||
|
||||
error[E0423]: expected value, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:45:5
|
||||
|
|
||||
45 | a::b.J
|
||||
| ^^^^ did you mean `a::b::J`?
|
||||
| ^^^^--
|
||||
| |
|
||||
| did you mean `a::b::J`?
|
||||
|
||||
error[E0423]: expected value, found module `a`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:51:5
|
||||
|
|
||||
51 | a.b.f();
|
||||
| ^ did you mean `a::b`?
|
||||
| ^--
|
||||
| |
|
||||
| did you mean `a::b`?
|
||||
|
||||
error[E0423]: expected value, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:55:12
|
||||
|
|
||||
55 | v.push(a::b);
|
||||
| ^^^^ did you mean `a::I`?
|
||||
| ^^^-
|
||||
| |
|
||||
| did you mean `I`?
|
||||
|
||||
error[E0423]: expected value, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:61:5
|
||||
|
|
||||
61 | a::b.f()
|
||||
| ^^^^ did you mean `a::b::f(...)`?
|
||||
| ^^^^----
|
||||
| |
|
||||
| did you mean `a::b::f(...)`?
|
||||
|
||||
error[E0423]: expected value, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:67:5
|
||||
|
|
||||
67 | a::b
|
||||
| ^^^^ did you mean `a::I`?
|
||||
| ^^^-
|
||||
| |
|
||||
| did you mean `I`?
|
||||
|
||||
error[E0423]: expected function, found module `a::b`
|
||||
--> $DIR/suggest-path-instead-of-mod-dot-item.rs:73:5
|
||||
|
|
||||
73 | a::b()
|
||||
| ^^^^ did you mean `a::I`?
|
||||
| ^^^-
|
||||
| |
|
||||
| did you mean `I`?
|
||||
|
||||
error: main function not found
|
||||
|
||||
|
@ -2,7 +2,7 @@ error[E0405]: cannot find trait `Nonexist` in this scope
|
||||
--> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:11:8
|
||||
|
|
||||
11 | fn f<F:Nonexist(isize) -> isize>(x: F) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
|
||||
| ^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0404]: expected trait, found type alias `Typedef`
|
||||
--> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:17:8
|
||||
|
Loading…
x
Reference in New Issue
Block a user