More precise spans for HIR paths

This commit is contained in:
Vadim Petrochenkov 2021-03-13 19:14:18 +03:00
parent 2ccf06302c
commit 7e66e9d6b0
22 changed files with 60 additions and 30 deletions

View file

@ -149,9 +149,17 @@ impl PathSegment {
pub fn from_ident(ident: Ident) -> Self { pub fn from_ident(ident: Ident) -> Self {
PathSegment { ident, id: DUMMY_NODE_ID, args: None } PathSegment { ident, id: DUMMY_NODE_ID, args: None }
} }
pub fn path_root(span: Span) -> Self { pub fn path_root(span: Span) -> Self {
PathSegment::from_ident(Ident::new(kw::PathRoot, span)) 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. /// The arguments of a path segment.

View file

@ -30,6 +30,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let partial_res = let partial_res =
self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err)); 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 proj_start = p.segments.len() - partial_res.unresolved_segments();
let path = self.arena.alloc(hir::Path { let path = self.arena.alloc(hir::Path {
res: self.lower_res(partial_res.base_res()), 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. // 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 // e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
// `<I as Iterator>::Item::default`. // `<I as Iterator>::Item::default`.
let new_id = self.next_id(); 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", // 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` // 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone` // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
for (i, segment) in p.segments.iter().enumerate().skip(proj_start) { 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, p.span,
segment, segment,
param_mode, param_mode,
@ -150,7 +153,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
itctx.reborrow(), itctx.reborrow(),
None, 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. // It's finished, return the extension of the right node type.
if i == p.segments.len() - 1 { if i == p.segments.len() - 1 {
@ -159,7 +162,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Wrap the associated extension in another type node. // Wrap the associated extension in another type node.
let new_id = self.next_id(); 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. // We should've returned in the for loop above.

View file

@ -1809,7 +1809,7 @@ impl<'hir> QPath<'hir> {
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match *self { match *self {
QPath::Resolved(_, path) => path.span, 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, QPath::LangItem(_, span) => span,
} }
} }

View file

@ -104,7 +104,7 @@ pub fn report_object_safety_error(
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>", <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) // Avoid emitting error caused by non-existing method (#58734)
err.cancel(); err.cancel();
} }

View file

@ -1414,8 +1414,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
name: Symbol, name: Symbol,
) { ) {
let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type"); let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
if let (Some(_), Ok(snippet)) = ( if let (true, Ok(snippet)) = (
self.tcx().sess.confused_type_with_std_module.borrow().get(&span), 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), self.tcx().sess.source_map().span_to_snippet(span),
) { ) {
err.span_suggestion( err.span_suggestion(

View file

@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
qpath: &QPath<'_>, qpath: &QPath<'_>,
hir_id: hir::HirId, hir_id: hir::HirId,
) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> { ) -> 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 (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
let variant = match def { let variant = match def {
Res::Err => { Res::Err => {

View file

@ -5,4 +5,5 @@ pub fn main() {
//~^ ERROR only auto traits can be used as additional traits in a trait object //~^ ERROR only auto traits can be used as additional traits in a trait object
//~| ERROR the size for values of type //~| ERROR the size for values of type
//~| ERROR the size for values of type //~| ERROR the size for values of type
//~| ERROR the size for values of type
} }

View file

@ -31,7 +31,20 @@ LL | let x: Vec<dyn Trait + Sized> = Vec::new();
= help: the trait `Sized` is not implemented for `dyn Trait` = help: the trait `Sized` is not implemented for `dyn Trait`
= note: required by `Vec::<T>::new` = note: required by `Vec::<T>::new`
error: aborting due to 3 previous errors error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
--> $DIR/bad-sized.rs:4:37
|
LL | let x: Vec<dyn Trait + Sized> = Vec::new();
| ^^^ doesn't have a size known at compile-time
|
::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
| - required by this bound in `Vec`
|
= help: the trait `Sized` is not implemented for `dyn Trait`
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0225, E0277. Some errors have detailed explanations: E0225, E0277.
For more information about an error, try `rustc --explain E0225`. For more information about an error, try `rustc --explain E0225`.

View file

@ -10,7 +10,7 @@ warning: use of deprecated struct `MustUseDeprecated`
--> $DIR/cfg-attr-multi-true.rs:19:5 --> $DIR/cfg-attr-multi-true.rs:19:5
| |
LL | MustUseDeprecated::new(); LL | MustUseDeprecated::new();
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
warning: use of deprecated struct `MustUseDeprecated` warning: use of deprecated struct `MustUseDeprecated`
--> $DIR/cfg-attr-multi-true.rs:13:17 --> $DIR/cfg-attr-multi-true.rs:13:17

View file

@ -2,7 +2,7 @@ error[E0223]: ambiguous associated type
--> $DIR/issue-78622.rs:5:5 --> $DIR/issue-78622.rs:5:5
| |
LL | S::A::<f> {} LL | S::A::<f> {}
| ^^^^^^^^^ help: use fully-qualified syntax: `<S as Trait>::A` | ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
error: aborting due to previous error error: aborting due to previous error

View file

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

View file

@ -13,7 +13,7 @@ help: the lifetime requirements from the `impl` do not correspond to the require
--> $DIR/issue-75361-mismatched-impl.rs:12:55 --> $DIR/issue-75361-mismatched-impl.rs:12:55
| |
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>; LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
| ^^^^^^^^^^^^^^ consider borrowing this type parameter in the trait | ^^^^ consider borrowing this type parameter in the trait
error: aborting due to previous error error: aborting due to previous error

View file

@ -222,7 +222,7 @@ error: type `priv_parent_substs::Priv` is private
--> $DIR/associated-item-privacy-inherent.rs:101:9 --> $DIR/associated-item-privacy-inherent.rs:101:9
| |
LL | Pub::CONST; LL | Pub::CONST;
| ^^^^^^^^^^ private type | ^^^ private type
... ...
LL | priv_parent_substs::mac!(); LL | priv_parent_substs::mac!();
| --------------------------- in this macro invocation | --------------------------- in this macro invocation

View file

@ -56,7 +56,7 @@ error: type `Priv` is private
--> $DIR/private-inferred-type.rs:104:5 --> $DIR/private-inferred-type.rs:104:5
| |
LL | m::Pub::INHERENT_ASSOC_CONST; LL | m::Pub::INHERENT_ASSOC_CONST;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ private type | ^^^^^^ private type
error: type `Priv` is private error: type `Priv` is private
--> $DIR/private-inferred-type.rs:105:5 --> $DIR/private-inferred-type.rs:105:5

View file

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

View file

@ -100,7 +100,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $DIR/generics-default-stability.rs:160:28 --> $DIR/generics-default-stability.rs:160:28
| |
LL | let _: Alias4<isize> = Alias4::Some(1); LL | let _: Alias4<isize> = Alias4::Some(1);
| ^^^^^^^^^^^^ | ^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias4`: test warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $DIR/generics-default-stability.rs:160:12 --> $DIR/generics-default-stability.rs:160:12
@ -124,7 +124,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $DIR/generics-default-stability.rs:166:28 --> $DIR/generics-default-stability.rs:166:28
| |
LL | let _: Alias4<isize> = Alias4::Some(0); LL | let _: Alias4<isize> = Alias4::Some(0);
| ^^^^^^^^^^^^ | ^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias4`: test warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $DIR/generics-default-stability.rs:166:12 --> $DIR/generics-default-stability.rs:166:12
@ -136,7 +136,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
--> $DIR/generics-default-stability.rs:171:28 --> $DIR/generics-default-stability.rs:171:28
| |
LL | let _: Alias5<isize> = Alias5::Some(1); LL | let _: Alias5<isize> = Alias5::Some(1);
| ^^^^^^^^^^^^ | ^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias5`: test warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
--> $DIR/generics-default-stability.rs:171:12 --> $DIR/generics-default-stability.rs:171:12
@ -160,7 +160,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
--> $DIR/generics-default-stability.rs:178:28 --> $DIR/generics-default-stability.rs:178:28
| |
LL | let _: Alias5<isize> = Alias5::Some(0); LL | let _: Alias5<isize> = Alias5::Some(0);
| ^^^^^^^^^^^^ | ^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias5`: test warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
--> $DIR/generics-default-stability.rs:178:12 --> $DIR/generics-default-stability.rs:178:12

View file

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

View file

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

View file

@ -2,12 +2,12 @@ error[E0223]: ambiguous associated type
--> $DIR/suggest-std-when-using-type.rs:2:14 --> $DIR/suggest-std-when-using-type.rs:2:14
| |
LL | let pi = f32::consts::PI; LL | let pi = f32::consts::PI;
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
help: you are looking for the module in `std`, not the primitive type help: you are looking for the module in `std`, not the primitive type
| |
LL | let pi = std::f32::consts::PI; LL | let pi = std::f32::consts::PI;
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error[E0599]: no function or associated item named `from_utf8` found for type `str` in the current scope error[E0599]: no function or associated item named `from_utf8` found for type `str` in the current scope
--> $DIR/suggest-std-when-using-type.rs:5:14 --> $DIR/suggest-std-when-using-type.rs:5:14

View file

@ -113,7 +113,7 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object
--> $DIR/item-privacy.rs:101:5 --> $DIR/item-privacy.rs:101:5
| |
LL | C::A; LL | C::A;
| ^^^^ `assoc_const::C` cannot be made into an object | ^ `assoc_const::C` cannot be made into an object
| |
= help: consider moving `C` to another trait = help: consider moving `C` to another trait
= help: consider moving `B` to another trait = help: consider moving `B` to another trait

View file

@ -31,7 +31,7 @@ LL | | }
| |_- type parameter `A` must be specified for this | |_- type parameter `A` must be specified for this
... ...
LL | let e = Bar::<usize>::lol(); LL | let e = Bar::<usize>::lol();
| ^^^^^^^^^^^^^^^^^ missing reference to `A` | ^^^^^^^^^^^^ missing reference to `A`
| |
= note: because of the default `Self` reference, type parameters must be specified on object types = note: because of the default `Self` reference, type parameters must be specified on object types

View file

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