Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

More precise spans for HIR paths #83092

Merged
merged 2 commits into from
Mar 17, 2021
Merged
Show file tree
Hide file tree
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
Expand Up @@ -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.
Expand Down
13 changes: 8 additions & 5 deletions compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
Expand Down Expand Up @@ -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.
Expand All @@ -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",
Expand All @@ -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,
Expand All @@ -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 {
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
Expand Down
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
Expand Up @@ -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();
}
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
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
Expand Up @@ -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 => {
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/bad/bad-sized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-78622.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/mir/issue-80742.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/privacy/private-inferred-type.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/regions/issue-28848.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
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
Expand Up @@ -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
Expand All @@ -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
Expand Down
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
Expand Up @@ -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
|
Expand Down
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
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/traits/item-privacy.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
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
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/wf/wf-static-method.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 12 additions & 11 deletions src/tools/clippy/tests/ui/use_self.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 12 additions & 11 deletions src/tools/clippy/tests/ui/use_self.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
16 changes: 2 additions & 14 deletions src/tools/clippy/tests/ui/use_self.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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