Skip to content

Commit 70edab8

Browse files
authored
Rollup merge of rust-lang#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 rust-lang#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

+8
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

+8-5
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

+1-1
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

+1-1
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

+7-2
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

+1-1
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

+1
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

+14-1
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

+1-1
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

+1-1
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

src/test/ui/mir/issue-80742.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ LL | struct Inline<T>
5656
| - required by this bound in `Inline`
5757
...
5858
LL | let dst = Inline::<dyn Debug>::new(0);
59-
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
59+
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
6060
|
6161
= help: the trait `Sized` is not implemented for `dyn Debug`
6262
help: consider relaxing the implicit `Sized` restriction

src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ help: the lifetime requirements from the `impl` do not correspond to the require
1313
--> $DIR/issue-75361-mismatched-impl.rs:12:55
1414
|
1515
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
16-
| ^^^^^^^^^^^^^^ consider borrowing this type parameter in the trait
16+
| ^^^^ consider borrowing this type parameter in the trait
1717

1818
error: aborting due to previous error
1919

src/test/ui/privacy/associated-item-privacy-inherent.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ error: type `priv_parent_substs::Priv` is private
222222
--> $DIR/associated-item-privacy-inherent.rs:101:9
223223
|
224224
LL | Pub::CONST;
225-
| ^^^^^^^^^^ private type
225+
| ^^^ private type
226226
...
227227
LL | priv_parent_substs::mac!();
228228
| --------------------------- in this macro invocation

src/test/ui/privacy/private-inferred-type.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ error: type `Priv` is private
5656
--> $DIR/private-inferred-type.rs:104:5
5757
|
5858
LL | m::Pub::INHERENT_ASSOC_CONST;
59-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ private type
59+
| ^^^^^^ private type
6060

6161
error: type `Priv` is private
6262
--> $DIR/private-inferred-type.rs:105:5

src/test/ui/regions/issue-28848.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0478]: lifetime bound not satisfied
22
--> $DIR/issue-28848.rs:10:5
33
|
44
LL | Foo::<'a, 'b>::xmute(u)
5-
| ^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^
66
|
77
note: lifetime parameter instantiated with the lifetime `'b` as defined on the function body at 9:16
88
--> $DIR/issue-28848.rs:9:16

src/test/ui/stability-attribute/generics-default-stability.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
100100
--> $DIR/generics-default-stability.rs:160:28
101101
|
102102
LL | let _: Alias4<isize> = Alias4::Some(1);
103-
| ^^^^^^^^^^^^
103+
| ^^^^^^
104104

105105
warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
106106
--> $DIR/generics-default-stability.rs:160:12
@@ -124,7 +124,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
124124
--> $DIR/generics-default-stability.rs:166:28
125125
|
126126
LL | let _: Alias4<isize> = Alias4::Some(0);
127-
| ^^^^^^^^^^^^
127+
| ^^^^^^
128128

129129
warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
130130
--> $DIR/generics-default-stability.rs:166:12
@@ -136,7 +136,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
136136
--> $DIR/generics-default-stability.rs:171:28
137137
|
138138
LL | let _: Alias5<isize> = Alias5::Some(1);
139-
| ^^^^^^^^^^^^
139+
| ^^^^^^
140140

141141
warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
142142
--> $DIR/generics-default-stability.rs:171:12
@@ -160,7 +160,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
160160
--> $DIR/generics-default-stability.rs:178:28
161161
|
162162
LL | let _: Alias5<isize> = Alias5::Some(0);
163-
| ^^^^^^^^^^^^
163+
| ^^^^^^
164164

165165
warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
166166
--> $DIR/generics-default-stability.rs:178:12

src/test/ui/structs/struct-path-associated-type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ error[E0071]: expected struct, variant or union type, found associated type
1414
--> $DIR/struct-path-associated-type.rs:14:13
1515
|
1616
LL | let z = T::A::<u8> {};
17-
| ^^^^^^^^^^ not a struct
17+
| ^^^^ not a struct
1818

1919
error[E0071]: expected struct, variant or union type, found associated type
2020
--> $DIR/struct-path-associated-type.rs:18:9
@@ -38,7 +38,7 @@ error[E0223]: ambiguous associated type
3838
--> $DIR/struct-path-associated-type.rs:33:13
3939
|
4040
LL | let z = S::A::<u8> {};
41-
| ^^^^^^^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
41+
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
4242

4343
error[E0223]: ambiguous associated type
4444
--> $DIR/struct-path-associated-type.rs:35:9

src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satis
1111
--> $DIR/mut-borrow-needed-by-trait.rs:17:14
1212
|
1313
LL | let fp = BufWriter::new(fp);
14-
| ^^^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
14+
| ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
1515
|
1616
::: $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
1717
|

src/test/ui/suggestions/suggest-std-when-using-type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0223]: ambiguous associated type
22
--> $DIR/suggest-std-when-using-type.rs:2:14
33
|
44
LL | let pi = f32::consts::PI;
5-
| ^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^
66
|
77
help: you are looking for the module in `std`, not the primitive type
88
|
99
LL | let pi = std::f32::consts::PI;
10-
| ^^^^^^^^^^^^^^^^^^^^
10+
| ^^^^^^^^^^^^^^^^
1111

1212
error[E0599]: no function or associated item named `from_utf8` found for type `str` in the current scope
1313
--> $DIR/suggest-std-when-using-type.rs:5:14

src/test/ui/traits/item-privacy.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object
113113
--> $DIR/item-privacy.rs:101:5
114114
|
115115
LL | C::A;
116-
| ^^^^ `assoc_const::C` cannot be made into an object
116+
| ^ `assoc_const::C` cannot be made into an object
117117
|
118118
= help: consider moving `C` to another trait
119119
= help: consider moving `B` to another trait

src/test/ui/unspecified-self-in-trait-ref.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ LL | | }
3131
| |_- type parameter `A` must be specified for this
3232
...
3333
LL | let e = Bar::<usize>::lol();
34-
| ^^^^^^^^^^^^^^^^^ missing reference to `A`
34+
| ^^^^^^^^^^^^ missing reference to `A`
3535
|
3636
= note: because of the default `Self` reference, type parameters must be specified on object types
3737

src/test/ui/wf/wf-static-method.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ error[E0478]: lifetime bound not satisfied
1919
--> $DIR/wf-static-method.rs:26:18
2020
|
2121
LL | let me = Self::make_me();
22-
| ^^^^^^^^^^^^^
22+
| ^^^^
2323
|
2424
note: lifetime parameter instantiated with the lifetime `'b` as defined on the impl at 23:10
2525
--> $DIR/wf-static-method.rs:23:10

src/tools/clippy/tests/ui/use_self.fixed

+12-11
Original file line numberDiff line numberDiff line change
@@ -312,17 +312,18 @@ mod issue4140 {
312312
fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;
313313
}
314314

315-
impl<F, T> TryFrom<F> for T
316-
where
317-
T: From<F>,
318-
{
319-
type From = Self;
320-
type To = Self;
321-
322-
fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
323-
Ok(From::from(value))
324-
}
325-
}
315+
// FIXME: Suggested fix results in infinite recursion.
316+
// impl<F, T> TryFrom<F> for T
317+
// where
318+
// T: From<F>,
319+
// {
320+
// type From = Self::From;
321+
// type To = Self::To;
322+
323+
// fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
324+
// Ok(From::from(value))
325+
// }
326+
// }
326327

327328
impl From<bool> for i64 {
328329
type From = bool;

src/tools/clippy/tests/ui/use_self.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -312,17 +312,18 @@ mod issue4140 {
312312
fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;
313313
}
314314

315-
impl<F, T> TryFrom<F> for T
316-
where
317-
T: From<F>,
318-
{
319-
type From = T::From;
320-
type To = T::To;
321-
322-
fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
323-
Ok(From::from(value))
324-
}
325-
}
315+
// FIXME: Suggested fix results in infinite recursion.
316+
// impl<F, T> TryFrom<F> for T
317+
// where
318+
// T: From<F>,
319+
// {
320+
// type From = Self::From;
321+
// type To = Self::To;
322+
323+
// fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
324+
// Ok(From::from(value))
325+
// }
326+
// }
326327

327328
impl From<bool> for i64 {
328329
type From = bool;

src/tools/clippy/tests/ui/use_self.stderr

+2-14
Original file line numberDiff line numberDiff line change
@@ -157,22 +157,10 @@ LL | Foo { value }
157157
| ^^^ help: use the applicable keyword: `Self`
158158

159159
error: unnecessary structure name repetition
160-
--> $DIR/use_self.rs:319:21
161-
|
162-
LL | type From = T::From;
163-
| ^^^^^^^ help: use the applicable keyword: `Self`
164-
165-
error: unnecessary structure name repetition
166-
--> $DIR/use_self.rs:320:19
167-
|
168-
LL | type To = T::To;
169-
| ^^^^^ help: use the applicable keyword: `Self`
170-
171-
error: unnecessary structure name repetition
172-
--> $DIR/use_self.rs:453:13
160+
--> $DIR/use_self.rs:454:13
173161
|
174162
LL | A::new::<submod::B>(submod::B {})
175163
| ^ help: use the applicable keyword: `Self`
176164

177-
error: aborting due to 29 previous errors
165+
error: aborting due to 27 previous errors
178166

0 commit comments

Comments
 (0)