Rollup merge of #83092 - petrochenkov:qspan, r=estebank
More precise spans for HIR paths `Ty::assoc_item` is lowered to `<Ty>::assoc_item` in HIR, but `Ty` got span from the whole path. This PR fixes that, and adjusts some diagnostic code that relied on `Ty` having the whole path span. This is a pre-requisite for https://github.com/rust-lang/rust/pull/82868 (we cannot report suggestions like `Tr::assoc` -> `<dyn Tr>::assoc` with the current imprecise spans). r? ````@estebank````
This commit is contained in:
commit
70edab895d
27 changed files with 86 additions and 66 deletions
|
@ -149,9 +149,17 @@ impl PathSegment {
|
|||
pub fn from_ident(ident: Ident) -> Self {
|
||||
PathSegment { ident, id: DUMMY_NODE_ID, args: None }
|
||||
}
|
||||
|
||||
pub fn path_root(span: Span) -> Self {
|
||||
PathSegment::from_ident(Ident::new(kw::PathRoot, span))
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
match &self.args {
|
||||
Some(args) => self.ident.span.to(args.span()),
|
||||
None => self.ident.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The arguments of a path segment.
|
||||
|
|
|
@ -30,6 +30,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let partial_res =
|
||||
self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
|
||||
|
||||
let path_span_lo = p.span.shrink_to_lo();
|
||||
let proj_start = p.segments.len() - partial_res.unresolved_segments();
|
||||
let path = self.arena.alloc(hir::Path {
|
||||
res: self.lower_res(partial_res.base_res()),
|
||||
|
@ -108,7 +109,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
)
|
||||
},
|
||||
)),
|
||||
span: p.span,
|
||||
span: p.segments[..proj_start]
|
||||
.last()
|
||||
.map_or(path_span_lo, |segment| path_span_lo.to(segment.span())),
|
||||
});
|
||||
|
||||
// Simple case, either no projections, or only fully-qualified.
|
||||
|
@ -127,7 +130,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
|
||||
// `<I as Iterator>::Item::default`.
|
||||
let new_id = self.next_id();
|
||||
self.arena.alloc(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
|
||||
self.arena.alloc(self.ty_path(new_id, path.span, hir::QPath::Resolved(qself, path)))
|
||||
};
|
||||
|
||||
// Anything after the base path are associated "extensions",
|
||||
|
@ -141,7 +144,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
|
||||
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
|
||||
for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
|
||||
let segment = self.arena.alloc(self.lower_path_segment(
|
||||
let hir_segment = self.arena.alloc(self.lower_path_segment(
|
||||
p.span,
|
||||
segment,
|
||||
param_mode,
|
||||
|
@ -150,7 +153,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
itctx.reborrow(),
|
||||
None,
|
||||
));
|
||||
let qpath = hir::QPath::TypeRelative(ty, segment);
|
||||
let qpath = hir::QPath::TypeRelative(ty, hir_segment);
|
||||
|
||||
// It's finished, return the extension of the right node type.
|
||||
if i == p.segments.len() - 1 {
|
||||
|
@ -159,7 +162,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
// Wrap the associated extension in another type node.
|
||||
let new_id = self.next_id();
|
||||
ty = self.arena.alloc(self.ty_path(new_id, p.span, qpath));
|
||||
ty = self.arena.alloc(self.ty_path(new_id, path_span_lo.to(segment.span()), qpath));
|
||||
}
|
||||
|
||||
// We should've returned in the for loop above.
|
||||
|
|
|
@ -1809,7 +1809,7 @@ impl<'hir> QPath<'hir> {
|
|||
pub fn span(&self) -> Span {
|
||||
match *self {
|
||||
QPath::Resolved(_, path) => path.span,
|
||||
QPath::TypeRelative(_, ps) => ps.ident.span,
|
||||
QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
|
||||
QPath::LangItem(_, span) => span,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ pub fn report_object_safety_error(
|
|||
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
|
||||
);
|
||||
|
||||
if tcx.sess.trait_methods_not_found.borrow().contains(&span) {
|
||||
if tcx.sess.trait_methods_not_found.borrow().iter().any(|full_span| full_span.contains(span)) {
|
||||
// Avoid emitting error caused by non-existing method (#58734)
|
||||
err.cancel();
|
||||
}
|
||||
|
|
|
@ -1414,8 +1414,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
name: Symbol,
|
||||
) {
|
||||
let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
|
||||
if let (Some(_), Ok(snippet)) = (
|
||||
self.tcx().sess.confused_type_with_std_module.borrow().get(&span),
|
||||
if let (true, Ok(snippet)) = (
|
||||
self.tcx()
|
||||
.sess
|
||||
.confused_type_with_std_module
|
||||
.borrow()
|
||||
.keys()
|
||||
.any(|full_span| full_span.contains(span)),
|
||||
self.tcx().sess.source_map().span_to_snippet(span),
|
||||
) {
|
||||
err.span_suggestion(
|
||||
|
|
|
@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
qpath: &QPath<'_>,
|
||||
hir_id: hir::HirId,
|
||||
) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
|
||||
let path_span = qpath.qself_span();
|
||||
let path_span = qpath.span();
|
||||
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
|
||||
let variant = match def {
|
||||
Res::Err => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue