Skip to content

Commit 70edab8

Browse files
authored
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 #82868 (we cannot report suggestions like `Tr::assoc` -> `<dyn Tr>::assoc` with the current imprecise spans). r? ````@estebank````
2 parents 3122510 + e98b7d1 commit 70edab8

27 files changed

+88
-68
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,17 @@ impl PathSegment {
149149
pub fn from_ident(ident: Ident) -> Self {
150150
PathSegment { ident, id: DUMMY_NODE_ID, args: None }
151151
}
152+
152153
pub fn path_root(span: Span) -> Self {
153154
PathSegment::from_ident(Ident::new(kw::PathRoot, span))
154155
}
156+
157+
pub fn span(&self) -> Span {
158+
match &self.args {
159+
Some(args) => self.ident.span.to(args.span()),
160+
None => self.ident.span,
161+
}
162+
}
155163
}
156164

157165
/// The arguments of a path segment.

compiler/rustc_ast_lowering/src/path.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
3030
let partial_res =
3131
self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
3232

33+
let path_span_lo = p.span.shrink_to_lo();
3334
let proj_start = p.segments.len() - partial_res.unresolved_segments();
3435
let path = self.arena.alloc(hir::Path {
3536
res: self.lower_res(partial_res.base_res()),
@@ -108,7 +109,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
108109
)
109110
},
110111
)),
111-
span: p.span,
112+
span: p.segments[..proj_start]
113+
.last()
114+
.map_or(path_span_lo, |segment| path_span_lo.to(segment.span())),
112115
});
113116

114117
// Simple case, either no projections, or only fully-qualified.
@@ -127,7 +130,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
127130
// e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
128131
// `<I as Iterator>::Item::default`.
129132
let new_id = self.next_id();
130-
self.arena.alloc(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
133+
self.arena.alloc(self.ty_path(new_id, path.span, hir::QPath::Resolved(qself, path)))
131134
};
132135

133136
// Anything after the base path are associated "extensions",
@@ -141,7 +144,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
141144
// 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
142145
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
143146
for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
144-
let segment = self.arena.alloc(self.lower_path_segment(
147+
let hir_segment = self.arena.alloc(self.lower_path_segment(
145148
p.span,
146149
segment,
147150
param_mode,
@@ -150,7 +153,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
150153
itctx.reborrow(),
151154
None,
152155
));
153-
let qpath = hir::QPath::TypeRelative(ty, segment);
156+
let qpath = hir::QPath::TypeRelative(ty, hir_segment);
154157

155158
// It's finished, return the extension of the right node type.
156159
if i == p.segments.len() - 1 {
@@ -159,7 +162,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
159162

160163
// Wrap the associated extension in another type node.
161164
let new_id = self.next_id();
162-
ty = self.arena.alloc(self.ty_path(new_id, p.span, qpath));
165+
ty = self.arena.alloc(self.ty_path(new_id, path_span_lo.to(segment.span()), qpath));
163166
}
164167

165168
// We should've returned in the for loop above.

compiler/rustc_hir/src/hir.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1809,7 +1809,7 @@ impl<'hir> QPath<'hir> {
18091809
pub fn span(&self) -> Span {
18101810
match *self {
18111811
QPath::Resolved(_, path) => path.span,
1812-
QPath::TypeRelative(_, ps) => ps.ident.span,
1812+
QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
18131813
QPath::LangItem(_, span) => span,
18141814
}
18151815
}

compiler/rustc_infer/src/traits/error_reporting/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub fn report_object_safety_error(
104104
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
105105
);
106106

107-
if tcx.sess.trait_methods_not_found.borrow().contains(&span) {
107+
if tcx.sess.trait_methods_not_found.borrow().iter().any(|full_span| full_span.contains(span)) {
108108
// Avoid emitting error caused by non-existing method (#58734)
109109
err.cancel();
110110
}

compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,8 +1414,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14141414
name: Symbol,
14151415
) {
14161416
let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
1417-
if let (Some(_), Ok(snippet)) = (
1418-
self.tcx().sess.confused_type_with_std_module.borrow().get(&span),
1417+
if let (true, Ok(snippet)) = (
1418+
self.tcx()
1419+
.sess
1420+
.confused_type_with_std_module
1421+
.borrow()
1422+
.keys()
1423+
.any(|full_span| full_span.contains(span)),
14191424
self.tcx().sess.source_map().span_to_snippet(span),
14201425
) {
14211426
err.span_suggestion(

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
439439
qpath: &QPath<'_>,
440440
hir_id: hir::HirId,
441441
) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
442-
let path_span = qpath.qself_span();
442+
let path_span = qpath.span();
443443
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
444444
let variant = match def {
445445
Res::Err => {

src/test/ui/bad/bad-sized.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ pub fn main() {
55
//~^ ERROR only auto traits can be used as additional traits in a trait object
66
//~| ERROR the size for values of type
77
//~| ERROR the size for values of type
8+
//~| ERROR the size for values of type
89
}

src/test/ui/bad/bad-sized.stderr

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,20 @@ LL | let x: Vec<dyn Trait + Sized> = Vec::new();
3131
= help: the trait `Sized` is not implemented for `dyn Trait`
3232
= note: required by `Vec::<T>::new`
3333

34-
error: aborting due to 3 previous errors
34+
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
35+
--> $DIR/bad-sized.rs:4:37
36+
|
37+
LL | let x: Vec<dyn Trait + Sized> = Vec::new();
38+
| ^^^ doesn't have a size known at compile-time
39+
|
40+
::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
41+
|
42+
LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
43+
| - required by this bound in `Vec`
44+
|
45+
= help: the trait `Sized` is not implemented for `dyn Trait`
46+
47+
error: aborting due to 4 previous errors
3548

3649
Some errors have detailed explanations: E0225, E0277.
3750
For more information about an error, try `rustc --explain E0225`.

src/test/ui/conditional-compilation/cfg-attr-multi-true.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ warning: use of deprecated struct `MustUseDeprecated`
1010
--> $DIR/cfg-attr-multi-true.rs:19:5
1111
|
1212
LL | MustUseDeprecated::new();
13-
| ^^^^^^^^^^^^^^^^^^^^^^
13+
| ^^^^^^^^^^^^^^^^^
1414

1515
warning: use of deprecated struct `MustUseDeprecated`
1616
--> $DIR/cfg-attr-multi-true.rs:13:17

src/test/ui/issues/issue-78622.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0223]: ambiguous associated type
22
--> $DIR/issue-78622.rs:5:5
33
|
44
LL | S::A::<f> {}
5-
| ^^^^^^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
5+
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
66

77
error: aborting due to previous error
88

0 commit comments

Comments
 (0)