Skip to content

More precise spans for HIR paths #83092

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 2 commits into from
Mar 17, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
@@ -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.
13 changes: 8 additions & 5 deletions compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -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();
}
9 changes: 7 additions & 2 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
@@ -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(
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
@@ -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 => {
1 change: 1 addition & 0 deletions src/test/ui/bad/bad-sized.rs
Original file line number Diff line number Diff line change
@@ -5,4 +5,5 @@ pub fn main() {
//~^ 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
}
15 changes: 14 additions & 1 deletion src/test/ui/bad/bad-sized.stderr
Original file line number Diff line number Diff line change
@@ -31,7 +31,20 @@ LL | let x: Vec<dyn Trait + Sized> = Vec::new();
= help: the trait `Sized` is not implemented for `dyn Trait`
= 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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find the relevant span-based error filtering logic for this case.

--> $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.
For more information about an error, try `rustc --explain E0225`.
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ warning: use of deprecated struct `MustUseDeprecated`
--> $DIR/cfg-attr-multi-true.rs:19:5
|
LL | MustUseDeprecated::new();
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^

warning: use of deprecated struct `MustUseDeprecated`
--> $DIR/cfg-attr-multi-true.rs:13:17
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-78622.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0223]: ambiguous associated type
--> $DIR/issue-78622.rs:5:5
|
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

2 changes: 1 addition & 1 deletion src/test/ui/mir/issue-80742.stderr
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ LL | struct Inline<T>
| - required by this bound in `Inline`
...
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: consider relaxing the implicit `Sized` restriction
Original file line number Diff line number Diff line change
@@ -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
|
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

Original file line number Diff line number Diff line change
@@ -222,7 +222,7 @@ error: type `priv_parent_substs::Priv` is private
--> $DIR/associated-item-privacy-inherent.rs:101:9
|
LL | Pub::CONST;
| ^^^^^^^^^^ private type
| ^^^ private type
...
LL | priv_parent_substs::mac!();
| --------------------------- in this macro invocation
2 changes: 1 addition & 1 deletion src/test/ui/privacy/private-inferred-type.stderr
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ error: type `Priv` is private
--> $DIR/private-inferred-type.rs:104:5
|
LL | m::Pub::INHERENT_ASSOC_CONST;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ private type
| ^^^^^^ private type

error: type `Priv` is private
--> $DIR/private-inferred-type.rs:105:5
2 changes: 1 addition & 1 deletion src/test/ui/regions/issue-28848.stderr
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ error[E0478]: lifetime bound not satisfied
--> $DIR/issue-28848.rs:10:5
|
LL | Foo::<'a, 'b>::xmute(u)
| ^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'b` as defined on the function body at 9:16
--> $DIR/issue-28848.rs:9:16
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $DIR/generics-default-stability.rs:160:28
|
LL | let _: Alias4<isize> = Alias4::Some(1);
| ^^^^^^^^^^^^
| ^^^^^^

warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $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
|
LL | let _: Alias4<isize> = Alias4::Some(0);
| ^^^^^^^^^^^^
| ^^^^^^

warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $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
|
LL | let _: Alias5<isize> = Alias5::Some(1);
| ^^^^^^^^^^^^
| ^^^^^^

warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
--> $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
|
LL | let _: Alias5<isize> = Alias5::Some(0);
| ^^^^^^^^^^^^
| ^^^^^^

warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
--> $DIR/generics-default-stability.rs:178:12
4 changes: 2 additions & 2 deletions src/test/ui/structs/struct-path-associated-type.stderr
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ error[E0071]: expected struct, variant or union type, found associated type
--> $DIR/struct-path-associated-type.rs:14:13
|
LL | let z = T::A::<u8> {};
| ^^^^^^^^^^ not a struct
| ^^^^ not a struct

error[E0071]: expected struct, variant or union type, found associated type
--> $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
|
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
--> $DIR/struct-path-associated-type.rs:35:9
2 changes: 1 addition & 1 deletion src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr
Original file line number Diff line number Diff line change
@@ -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
|
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
|
4 changes: 2 additions & 2 deletions src/test/ui/suggestions/suggest-std-when-using-type.stderr
Original file line number Diff line number Diff line change
@@ -2,12 +2,12 @@ error[E0223]: ambiguous associated type
--> $DIR/suggest-std-when-using-type.rs:2:14
|
LL | let pi = f32::consts::PI;
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^
|
help: you are looking for the module in `std`, not the primitive type
|
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
--> $DIR/suggest-std-when-using-type.rs:5:14
2 changes: 1 addition & 1 deletion src/test/ui/traits/item-privacy.stderr
Original file line number Diff line number Diff line change
@@ -113,7 +113,7 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object
--> $DIR/item-privacy.rs:101:5
|
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 `B` to another trait
2 changes: 1 addition & 1 deletion src/test/ui/unspecified-self-in-trait-ref.stderr
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ LL | | }
| |_- type parameter `A` must be specified for this
...
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

2 changes: 1 addition & 1 deletion src/test/ui/wf/wf-static-method.stderr
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ error[E0478]: lifetime bound not satisfied
--> $DIR/wf-static-method.rs:26:18
|
LL | let me = Self::make_me();
| ^^^^^^^^^^^^^
| ^^^^
|
note: lifetime parameter instantiated with the lifetime `'b` as defined on the impl at 23:10
--> $DIR/wf-static-method.rs:23:10
23 changes: 12 additions & 11 deletions src/tools/clippy/tests/ui/use_self.fixed
Original file line number Diff line number Diff line change
@@ -312,17 +312,18 @@ mod issue4140 {
fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;
}

impl<F, T> TryFrom<F> for T
where
T: From<F>,
{
type From = Self;
type To = Self;

fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
Ok(From::from(value))
}
}
// FIXME: Suggested fix results in infinite recursion.
// impl<F, T> TryFrom<F> for T
// where
// T: From<F>,
// {
// type From = Self::From;
// type To = Self::To;

// fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
// Ok(From::from(value))
// }
// }

impl From<bool> for i64 {
type From = bool;
23 changes: 12 additions & 11 deletions src/tools/clippy/tests/ui/use_self.rs
Original file line number Diff line number Diff line change
@@ -312,17 +312,18 @@ mod issue4140 {
fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;
}

impl<F, T> TryFrom<F> for T
where
T: From<F>,
{
type From = T::From;
type To = T::To;

fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
Ok(From::from(value))
}
}
// FIXME: Suggested fix results in infinite recursion.
// impl<F, T> TryFrom<F> for T
// where
// T: From<F>,
// {
// type From = Self::From;
// type To = Self::To;

// fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
// Ok(From::from(value))
// }
// }

impl From<bool> for i64 {
type From = bool;
16 changes: 2 additions & 14 deletions src/tools/clippy/tests/ui/use_self.stderr
Original file line number Diff line number Diff line change
@@ -157,22 +157,10 @@ LL | Foo { value }
| ^^^ help: use the applicable keyword: `Self`

error: unnecessary structure name repetition
--> $DIR/use_self.rs:319:21
|
LL | type From = T::From;
| ^^^^^^^ help: use the applicable keyword: `Self`

error: unnecessary structure name repetition
--> $DIR/use_self.rs:320:19
|
LL | type To = T::To;
| ^^^^^ help: use the applicable keyword: `Self`

error: unnecessary structure name repetition
--> $DIR/use_self.rs:453:13
--> $DIR/use_self.rs:454:13
|
LL | A::new::<submod::B>(submod::B {})
| ^ help: use the applicable keyword: `Self`

error: aborting due to 29 previous errors
error: aborting due to 27 previous errors

Loading