Skip to content

Commit

Permalink
Rollup merge of #83092 - petrochenkov:qspan, r=estebank
Browse files Browse the repository at this point in the history
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````
JohnTitor authored Mar 17, 2021
2 parents 3122510 + e98b7d1 commit 70edab8
Showing 27 changed files with 88 additions and 68 deletions.
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
--> $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

Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ error: map with zero-sized value type
--> $DIR/zero_sized_btreemap_values.rs:64:35
|
LL | let _: BTreeMap<String, ()> = BTreeMap::new();
| ^^^^^^^^^^^^^
| ^^^^^^^^
|
= help: consider using a set instead

2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ error: map with zero-sized value type
--> $DIR/zero_sized_hashmap_values.rs:64:34
|
LL | let _: HashMap<String, ()> = HashMap::new();
| ^^^^^^^^^^^^
| ^^^^^^^
|
= help: consider using a set instead

0 comments on commit 70edab8

Please sign in to comment.