Skip to content

Add correct span for unsized types #143580

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
Copy link
Author

Choose a reason for hiding this comment

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

I have some questions about this two places

if let Some(pos) = snippet.find(&self_ty) {
let start = span.lo() + BytePos(pos as u32);
let end = start + BytePos(self_ty.len() as u32);
return Some(Span::new(start, end, span.ctxt(), span.parent()));
}

if let Some(pos) = snippet.find(&core_type) {
let start = span.lo() + BytePos(pos as u32);
let end = start + BytePos(core_type.len() as u32);
return Some(Span::new(start, end, span.ctxt(), span.parent()));
}

I feel like its a code duplication but I have no idea how to improve it, so i just leaved like this, if there any better way to write it, I`d love to learn best practices

Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
(err_msg, None)
};

if tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Sized) {
if let Some(refined_span) = self.report_sized_item(span, leaf_trait_predicate) {
span = refined_span;
}
}

let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);
*err.long_ty_path() = long_ty_file;

Expand Down Expand Up @@ -769,6 +775,48 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
applied_do_not_recommend
}

fn report_sized_item(
&self,
span: Span,
trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> Option<Span> {
let source_map = self.tcx.sess.source_map();
let snippet = source_map.span_to_snippet(span).ok()?;

// Skip macro
if snippet.contains('!') {
return None;
}

let self_ty = trait_pred.skip_binder().self_ty().to_string();

// Try to find the exact type in the source code
if let Some(pos) = snippet.find(&self_ty) {
let start = span.lo() + BytePos(pos as u32);
let end = start + BytePos(self_ty.len() as u32);
return Some(Span::new(start, end, span.ctxt(), span.parent()));
}

// Sanity check if exact match fails
let mut core_type = self_ty.as_str();
while core_type.starts_with('[') && core_type.ends_with(']') {
core_type = &core_type[1..core_type.len() - 1].trim();
if let Some(pos) = core_type.find(';') {
core_type = &core_type[..pos].trim();
}
}

// Try to find core type
if core_type != self_ty && !core_type.is_empty() {
if let Some(pos) = snippet.find(&core_type) {
let start = span.lo() + BytePos(pos as u32);
let end = start + BytePos(core_type.len() as u32);
return Some(Span::new(start, end, span.ctxt(), span.parent()));
}
}
None
}

fn report_host_effect_error(
&self,
predicate: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/abi/debug.generic.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -876,10 +876,10 @@ LL | type TestAbiNeSign = (fn(i32), fn(u32));
| ^^^^^^^^^^^^^^^^^^

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/debug.rs:68:46
--> $DIR/debug.rs:68:47
|
LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str)));
| ^^^^^^^^^^ 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 `str`
= note: only the last element of a tuple may have a dynamically sized type
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/abi/debug.riscv64.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -876,10 +876,10 @@ LL | type TestAbiNeSign = (fn(i32), fn(u32));
| ^^^^^^^^^^^^^^^^^^

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/debug.rs:68:46
--> $DIR/debug.rs:68:47
|
LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str)));
| ^^^^^^^^^^ 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 `str`
= note: only the last element of a tuple may have a dynamically sized type
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/associated-types/defaults-wf.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/defaults-wf.rs:7:15
--> $DIR/defaults-wf.rs:7:19
|
LL | type Ty = Vec<[u8]>;
| ^^^^^^^^^ 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 `[u8]`
note: required by an implicit `Sized` bound in `Vec`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/associated-types/issue-20005.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/issue-20005.rs:10:49
--> $DIR/issue-20005.rs:10:54
|
LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
| ^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^ doesn't have a size known at compile-time
|
note: required by an implicit `Sized` bound in `From`
--> $DIR/issue-20005.rs:1:12
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/trait-with-supertraits-needing-sized-self.rs:3:22
--> $DIR/trait-with-supertraits-needing-sized-self.rs:3:33
|
LL | trait ArithmeticOps: Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Div<Output=Self> {}
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^ doesn't have a size known at compile-time
|
note: required by an implicit `Sized` bound in `Add`
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/cast/unsized-union-ice.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/unsized-union-ice.rs:6:10
--> $DIR/unsized-union-ice.rs:6:33
|
LL | val: std::mem::ManuallyDrop<[u8]>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^ doesn't have a size known at compile-time
|
= help: within `ManuallyDrop<[u8]>`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `ManuallyDrop<[u8]>`
Expand Down
36 changes: 18 additions & 18 deletions tests/ui/closures/closure-return-type-must-be-sized.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
--> $DIR/closure-return-type-must-be-sized.rs:54:5
--> $DIR/closure-return-type-must-be-sized.rs:54:22
|
LL | a::foo::<fn() -> dyn A>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
= note: required because it appears within the type `fn() -> dyn A`

error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
--> $DIR/closure-return-type-must-be-sized.rs:55:14
--> $DIR/closure-return-type-must-be-sized.rs:55:22
|
LL | a::bar::<fn() -> dyn A, _>();
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
= note: required because it appears within the type `fn() -> dyn A`
Expand All @@ -22,28 +22,28 @@ LL | pub fn bar<F: FnOnce() -> R, R: ?Sized>() {}
| ^^^^^^^^^^^^^ required by this bound in `bar`

error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
--> $DIR/closure-return-type-must-be-sized.rs:56:5
--> $DIR/closure-return-type-must-be-sized.rs:56:22
|
LL | a::baz::<fn() -> dyn A>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
= note: required because it appears within the type `fn() -> dyn A`

error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
--> $DIR/closure-return-type-must-be-sized.rs:61:5
--> $DIR/closure-return-type-must-be-sized.rs:61:22
|
LL | b::foo::<fn() -> dyn A>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
= note: required because it appears within the type `fn() -> dyn A`

error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
--> $DIR/closure-return-type-must-be-sized.rs:62:14
--> $DIR/closure-return-type-must-be-sized.rs:62:22
|
LL | b::bar::<fn() -> dyn A, _>();
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
= note: required because it appears within the type `fn() -> dyn A`
Expand All @@ -54,28 +54,28 @@ LL | pub fn bar<F: Fn() -> R, R: ?Sized>() {}
| ^^^^^^^^^ required by this bound in `bar`

error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
--> $DIR/closure-return-type-must-be-sized.rs:63:5
--> $DIR/closure-return-type-must-be-sized.rs:63:22
|
LL | b::baz::<fn() -> dyn A>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
= note: required because it appears within the type `fn() -> dyn A`

error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
--> $DIR/closure-return-type-must-be-sized.rs:68:5
--> $DIR/closure-return-type-must-be-sized.rs:68:22
|
LL | c::foo::<fn() -> dyn A>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
= note: required because it appears within the type `fn() -> dyn A`

error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
--> $DIR/closure-return-type-must-be-sized.rs:69:14
--> $DIR/closure-return-type-must-be-sized.rs:69:22
|
LL | c::bar::<fn() -> dyn A, _>();
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
= note: required because it appears within the type `fn() -> dyn A`
Expand All @@ -86,10 +86,10 @@ LL | pub fn bar<F: FnMut() -> R, R: ?Sized>() {}
| ^^^^^^^^^^^^ required by this bound in `bar`

error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
--> $DIR/closure-return-type-must-be-sized.rs:70:5
--> $DIR/closure-return-type-must-be-sized.rs:70:22
|
LL | c::baz::<fn() -> dyn A>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
= note: required because it appears within the type `fn() -> dyn A`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/closures/missing-body.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ LL | fn main() { |b: [str; _]| {}; }
| ^ not allowed in type signatures

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/missing-body.rs:5:17
--> $DIR/missing-body.rs:5:18
|
LL | fn main() { |b: [str; _]| {}; }
| ^^^^^^^^ 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 `str`
= note: slice and array elements must have `Sized` type
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/consts/const-unsized.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
= note: statics and constants must have a statically known size

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/const-unsized.rs:15:1
--> $DIR/const-unsized.rs:15:20
|
LL | static STATIC_BAR: str = *"bar";
| ^^^^^^^^^^^^^^^^^^^^^^ 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 `str`
= note: statics and constants must have a statically known size
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/consts/dont-ctfe-unsized-initializer.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/dont-ctfe-unsized-initializer.rs:1:1
--> $DIR/dont-ctfe-unsized-initializer.rs:1:11
|
LL | static S: str = todo!();
| ^^^^^^^^^^^^^ 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 `str`
= note: statics and constants must have a statically known size
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/dst/dst-sized-trait-param.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
--> $DIR/dst-sized-trait-param.rs:7:6
--> $DIR/dst-sized-trait-param.rs:7:10
|
LL | impl Foo<[isize]> for usize { }
| ^^^^^^^^^^^^ 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 `[isize]`
note: required by an implicit `Sized` bound in `Foo`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/dyn-compatibility/supertrait-mentions-Self.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/supertrait-mentions-Self.rs:8:13
--> $DIR/supertrait-mentions-Self.rs:8:17
|
LL | trait Baz : Bar<Self> {
| ^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^ doesn't have a size known at compile-time
|
note: required by an implicit `Sized` bound in `Bar`
--> $DIR/supertrait-mentions-Self.rs:4:11
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/extern/extern-types-unsized.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ LL | fn assert_sized<T: ?Sized>() {}
| ++++++++

error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/extern-types-unsized.rs:28:20
--> $DIR/extern-types-unsized.rs:28:24
|
LL | assert_sized::<Bar<A>>();
| ^^^^^^ doesn't have a size known at compile-time
| ^ doesn't have a size known at compile-time
|
= help: within `Bar<A>`, the trait `Sized` is not implemented for `A`
note: required because it appears within the type `Bar<A>`
Expand Down Expand Up @@ -73,10 +73,10 @@ LL | struct Bar<T: ?Sized> {
| ^ required by this bound in `Bar`

error[E0277]: the size for values of type `A` cannot be known at compilation time
--> $DIR/extern-types-unsized.rs:32:20
--> $DIR/extern-types-unsized.rs:32:28
|
LL | assert_sized::<Bar<Bar<A>>>();
| ^^^^^^^^^^^ doesn't have a size known at compile-time
| ^ doesn't have a size known at compile-time
|
= help: within `Bar<Bar<A>>`, the trait `Sized` is not implemented for `A`
note: required because it appears within the type `Bar<A>`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/extern/issue-36122-accessing-externed-dst.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `[usize]` cannot be known at compilation time
--> $DIR/issue-36122-accessing-externed-dst.rs:3:9
--> $DIR/issue-36122-accessing-externed-dst.rs:3:24
|
LL | static symbol: [usize];
| ^^^^^^^^^^^^^^^^^^^^^^ 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 `[usize]`
= note: statics and constants must have a statically known size
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/feature-gates/feature-gate-trivial_bounds.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
--> $DIR/feature-gate-trivial_bounds.rs:52:32
|
LL | struct TwoStrs(str, str) where str: Sized;
| ^^^^^^^^^^ 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 `str`
= help: see issue #48214
Expand Down Expand Up @@ -136,7 +136,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
--> $DIR/feature-gate-trivial_bounds.rs:59:30
|
LL | fn return_str() -> str where str: Sized {
| ^^^^^^^^^^ 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 `str`
= help: see issue #48214
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/function-pointer/unsized-ret.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/unsized-ret.rs:10:11
--> $DIR/unsized-ret.rs:10:19
|
LL | foo::<fn() -> str, _>(None, ());
| ^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> str`, the trait `Sized` is not implemented for `str`
= note: required because it appears within the type `fn() -> str`
Expand All @@ -13,10 +13,10 @@ LL | fn foo<F: Fn<T>, T:std::marker::Tuple>(f: Option<F>, t: T) {
| ^^^^^ required by this bound in `foo`

error[E0277]: the size for values of type `(dyn std::fmt::Display + 'a)` cannot be known at compilation time
--> $DIR/unsized-ret.rs:13:11
--> $DIR/unsized-ret.rs:13:33
|
LL | foo::<for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&(),));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`, the trait `for<'a> Sized` is not implemented for `(dyn std::fmt::Display + 'a)`
= note: required because it appears within the type `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/higher-ranked/well-formed-aliases.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/well-formed-aliases.rs:5:52
--> $DIR/well-formed-aliases.rs:5:53
|
LL | fn test<T>(f: for<'a> fn(<&'a T as Trait>::Gat<&'a [str]>)) where for<'a> &'a T: Trait {}
| ^^^^^ 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 `str`
= note: slice and array elements must have `Sized` type
Expand Down
Loading
Loading