From 18c88822652198f69e17d821c453b0a7ad915669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 3 Mar 2020 15:58:47 -0800 Subject: [PATCH 1/2] Mention implicit `T: Sized` bound in E0277 errors --- src/librustc/ty/sty.rs | 8 +++++ .../traits/error_reporting/mod.rs | 34 +++++++++++++------ .../traits/error_reporting/suggestions.rs | 10 +++--- src/librustc_typeck/collect/type_of.rs | 6 +--- .../ui/consts/too_generic_eval_ice.stderr | 4 +-- .../dst/dst-object-from-unsized-type.stderr | 4 +-- src/test/ui/issues/issue-27060-2.stderr | 2 +- .../traits/trait-suggest-where-clause.stderr | 4 +-- src/test/ui/union/union-sized-field.stderr | 6 ++-- .../ui/unsized/unsized-bare-typaram.stderr | 2 +- src/test/ui/unsized/unsized-enum.stderr | 2 +- src/test/ui/unsized/unsized-enum2.stderr | 8 ++--- .../unsized-inherent-impl-self-type.stderr | 2 +- src/test/ui/unsized/unsized-struct.stderr | 4 +-- .../unsized-trait-impl-self-type.stderr | 2 +- .../unsized-trait-impl-trait-arg.stderr | 2 +- src/test/ui/unsized3.stderr | 12 +++---- src/test/ui/unsized5.stderr | 8 ++--- src/test/ui/unsized6.stderr | 26 +++++++------- src/test/ui/unsized7.stderr | 2 +- 20 files changed, 82 insertions(+), 66 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index ab2c98c89b4e6..0762977a5233c 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1927,6 +1927,14 @@ impl<'tcx> TyS<'tcx> { } } + #[inline] + pub fn is_some_param(&self) -> bool { + match self.kind { + ty::Param(_) => true, + _ => false, + } + } + #[inline] pub fn is_slice(&self) -> bool { match self.kind { diff --git a/src/librustc_infer/traits/error_reporting/mod.rs b/src/librustc_infer/traits/error_reporting/mod.rs index 63c3f827c2ecb..8f1d9d9989d25 100644 --- a/src/librustc_infer/traits/error_reporting/mod.rs +++ b/src/librustc_infer/traits/error_reporting/mod.rs @@ -584,17 +584,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { )) ); - let explanation = - if obligation.cause.code == ObligationCauseCode::MainFunctionType { - "consider using `()`, or a `Result`".to_owned() - } else { - format!( - "{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref.print_only_trait_path(), - trait_ref.self_ty(), - ) - }; + let explanation = if obligation.cause.code + == ObligationCauseCode::MainFunctionType + { + "consider using `()`, or a `Result`".to_owned() + } else if self.tcx.lang_items().sized_trait().map_or(false, |sized_id| { + let self_ty = trait_ref.self_ty(); + sized_id == trait_ref.def_id() + && self_ty.is_some_param() + && self_ty != self.tcx.types.self_param + }) { + // Detect type parameters with an implied `Sized` bound and explain + // it instead of giving a generic message. This will be displayed + // as a `help`. + "type parameters have an implicit `Sized` requirement by default" + .to_string() + } else { + format!( + "{}the trait `{}` is not implemented for `{}`", + pre_message, + trait_ref.print_only_trait_path(), + trait_ref.self_ty(), + ) + }; if self.suggest_add_reference_to_arg( &obligation, diff --git a/src/librustc_infer/traits/error_reporting/suggestions.rs b/src/librustc_infer/traits/error_reporting/suggestions.rs index d05955fb858c0..90cca7d28a388 100644 --- a/src/librustc_infer/traits/error_reporting/suggestions.rs +++ b/src/librustc_infer/traits/error_reporting/suggestions.rs @@ -28,9 +28,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { body_id: hir::HirId, ) { let self_ty = trait_ref.self_ty(); - let (param_ty, projection) = match &self_ty.kind { - ty::Param(_) => (true, None), - ty::Projection(projection) => (false, Some(projection)), + let projection = match &self_ty.kind { + ty::Param(_) => None, + ty::Projection(projection) => Some(projection), _ => return, }; @@ -64,7 +64,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { generics, kind: hir::TraitItemKind::Method(..), .. - }) if param_ty && self_ty == self.tcx.types.self_param => { + }) if self_ty.is_some_param() && self_ty == self.tcx.types.self_param => { // Restricting `Self` for a single method. suggest_restriction(&generics, "`Self`", err); return; @@ -138,7 +138,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }) | hir::Node::TraitItem(hir::TraitItem { generics, span, .. }) | hir::Node::ImplItem(hir::ImplItem { generics, span, .. }) - if param_ty => + if self_ty.is_some_param() => { // Missing generic type parameter bound. let param_name = self_ty.to_string(); diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index ec87112b7a8e0..9125329fe1529 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -440,17 +440,13 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { _ => None, }) .collect(); - let is_param = |ty: Ty<'_>| match ty.kind { - ty::Param(_) => true, - _ => false, - }; let bad_substs: Vec<_> = substs .iter() .enumerate() .filter_map(|(i, k)| { if let GenericArgKind::Type(ty) = k.unpack() { Some((i, ty)) } else { None } }) - .filter(|(_, ty)| !is_param(ty)) + .filter(|(_, ty)| !ty.is_some_param()) .collect(); if !bad_substs.is_empty() { let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id); diff --git a/src/test/ui/consts/too_generic_eval_ice.stderr b/src/test/ui/consts/too_generic_eval_ice.stderr index 8836de0023c9d..9f64624fccb76 100644 --- a/src/test/ui/consts/too_generic_eval_ice.stderr +++ b/src/test/ui/consts/too_generic_eval_ice.stderr @@ -23,7 +23,7 @@ LL | impl Foo { LL | [5; Self::HOST_SIZE] == [6; 0] | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `A` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error[E0277]: the size for values of type `B` cannot be known at compilation time @@ -38,7 +38,7 @@ LL | impl Foo { LL | [5; Self::HOST_SIZE] == [6; 0] | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `B` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error: aborting due to 3 previous errors diff --git a/src/test/ui/dst/dst-object-from-unsized-type.stderr b/src/test/ui/dst/dst-object-from-unsized-type.stderr index 80d188bf2f89b..03952a50388ef 100644 --- a/src/test/ui/dst/dst-object-from-unsized-type.stderr +++ b/src/test/ui/dst/dst-object-from-unsized-type.stderr @@ -6,7 +6,7 @@ LL | fn test1(t: &T) { LL | let u: &dyn Foo = t; | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: required for the cast to the object type `dyn Foo` @@ -18,7 +18,7 @@ LL | fn test2(t: &T) { LL | let v: &dyn Foo = t as &dyn Foo; | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: required for the cast to the object type `dyn Foo` diff --git a/src/test/ui/issues/issue-27060-2.stderr b/src/test/ui/issues/issue-27060-2.stderr index 1ddea73e00ae0..a93119a95ccdd 100644 --- a/src/test/ui/issues/issue-27060-2.stderr +++ b/src/test/ui/issues/issue-27060-2.stderr @@ -6,7 +6,7 @@ LL | pub struct Bad { LL | data: T, | ^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: the last field of a packed struct may only have a dynamically sized type if it does not need drop to be run diff --git a/src/test/ui/traits/trait-suggest-where-clause.stderr b/src/test/ui/traits/trait-suggest-where-clause.stderr index 9680d58b8c0c7..6b3fc0cd782e4 100644 --- a/src/test/ui/traits/trait-suggest-where-clause.stderr +++ b/src/test/ui/traits/trait-suggest-where-clause.stderr @@ -12,7 +12,7 @@ LL | mem::size_of::(); LL | pub const fn size_of() -> usize { | - required by this bound in `std::mem::size_of` | - = help: the trait `std::marker::Sized` is not implemented for `U` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error[E0277]: the size for values of type `U` cannot be known at compilation time @@ -29,7 +29,7 @@ LL | mem::size_of::>(); LL | pub const fn size_of() -> usize { | - required by this bound in `std::mem::size_of` | - = help: within `Misc`, the trait `std::marker::Sized` is not implemented for `U` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: required because it appears within the type `Misc` diff --git a/src/test/ui/union/union-sized-field.stderr b/src/test/ui/union/union-sized-field.stderr index 62dacd064bed0..460d44bf77928 100644 --- a/src/test/ui/union/union-sized-field.stderr +++ b/src/test/ui/union/union-sized-field.stderr @@ -6,7 +6,7 @@ LL | union Foo { LL | value: T, | ^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: no field of a union may have a dynamically sized type @@ -18,7 +18,7 @@ LL | struct Foo2 { LL | value: T, | ^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: only the last field of a struct may have a dynamically sized type @@ -30,7 +30,7 @@ LL | enum Foo3 { LL | Value(T), | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: no field of an enum variant may have a dynamically sized type diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr index 772de23e64cf0..bfc7a7e895e5a 100644 --- a/src/test/ui/unsized/unsized-bare-typaram.stderr +++ b/src/test/ui/unsized/unsized-bare-typaram.stderr @@ -8,7 +8,7 @@ LL | fn foo() { bar::() } | | | this type parameter needs to be `std::marker::Sized` | - = help: the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error: aborting due to previous error diff --git a/src/test/ui/unsized/unsized-enum.stderr b/src/test/ui/unsized/unsized-enum.stderr index 88f7b1f77aee0..37aea97834781 100644 --- a/src/test/ui/unsized/unsized-enum.stderr +++ b/src/test/ui/unsized/unsized-enum.stderr @@ -9,7 +9,7 @@ LL | fn foo2() { not_sized::>() } | | | this type parameter needs to be `std::marker::Sized` | - = help: the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error: aborting due to previous error diff --git a/src/test/ui/unsized/unsized-enum2.stderr b/src/test/ui/unsized/unsized-enum2.stderr index bc3b3831f3269..9cc08202de33a 100644 --- a/src/test/ui/unsized/unsized-enum2.stderr +++ b/src/test/ui/unsized/unsized-enum2.stderr @@ -7,7 +7,7 @@ LL | // parameter LL | VA(W), | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `W` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: no field of an enum variant may have a dynamically sized type @@ -20,7 +20,7 @@ LL | enum E { LL | VB{x: X}, | ^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: no field of an enum variant may have a dynamically sized type @@ -33,7 +33,7 @@ LL | enum E { LL | VC(isize, Y), | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `Y` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: no field of an enum variant may have a dynamically sized type @@ -46,7 +46,7 @@ LL | enum E { LL | VD{u: isize, x: Z}, | ^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `Z` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: no field of an enum variant may have a dynamically sized type diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr index 5688ae5b89a04..4e0245e6ec285 100644 --- a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr @@ -9,7 +9,7 @@ LL | impl S5 { | | | this type parameter needs to be `std::marker::Sized` | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error: aborting due to previous error diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr index 653fb5c1ae8dc..f6d9ecf44bcd9 100644 --- a/src/test/ui/unsized/unsized-struct.stderr +++ b/src/test/ui/unsized/unsized-struct.stderr @@ -9,7 +9,7 @@ LL | fn foo2() { not_sized::>() } | | | this type parameter needs to be `std::marker::Sized` | - = help: the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error[E0277]: the size for values of type `T` cannot be known at compilation time @@ -23,7 +23,7 @@ LL | fn bar2() { is_sized::>() } | | | this type parameter needs to be `std::marker::Sized` | - = help: within `Bar`, the trait `std::marker::Sized` is not implemented for `T` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: required because it appears within the type `Bar` diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr index 3597073e7e6c6..712dc75e025f1 100644 --- a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr @@ -9,7 +9,7 @@ LL | impl T3 for S5 { | | | this type parameter needs to be `std::marker::Sized` | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error: aborting due to previous error diff --git a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr index b37d9f9d5369e..058fe9e4771b3 100644 --- a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr +++ b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr @@ -6,7 +6,7 @@ LL | impl T2 for S4 { | | | this type parameter needs to be `std::marker::Sized` | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error: aborting due to previous error diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr index e97d00fc4741d..5bdfdd0952420 100644 --- a/src/test/ui/unsized3.stderr +++ b/src/test/ui/unsized3.stderr @@ -11,7 +11,7 @@ LL | fn f2(x: &X) { | | | required by this bound in `f2` | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error[E0277]: the size for values of type `X` cannot be known at compilation time @@ -27,7 +27,7 @@ LL | fn f4(x: &X) { | | | required by this bound in `f4` | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error[E0277]: the size for values of type `X` cannot be known at compilation time @@ -41,7 +41,7 @@ LL | fn f8(x1: &S, x2: &S) { LL | f5(x1); | ^^ doesn't have a size known at compile-time | - = help: within `S`, the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: required because it appears within the type `S` @@ -53,7 +53,7 @@ LL | fn f9(x1: Box>) { LL | f5(&(*x1, 34)); | ^^^^^^^^^^ doesn't have a size known at compile-time | - = help: within `S`, the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: required because it appears within the type `S` = note: only the last element of a tuple may have a dynamically sized type @@ -66,7 +66,7 @@ LL | fn f10(x1: Box>) { LL | f5(&(32, *x1)); | ^^^^^^^^^ doesn't have a size known at compile-time | - = help: within `({integer}, S)`, the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: required because it appears within the type `S` = note: required because it appears within the type `({integer}, S)` @@ -83,7 +83,7 @@ LL | fn f10(x1: Box>) { LL | f5(&(32, *x1)); | ^^^^^^^^^^ doesn't have a size known at compile-time | - = help: within `({integer}, S)`, the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: required because it appears within the type `S` = note: required because it appears within the type `({integer}, S)` diff --git a/src/test/ui/unsized5.stderr b/src/test/ui/unsized5.stderr index de4da309791c0..72b418900addb 100644 --- a/src/test/ui/unsized5.stderr +++ b/src/test/ui/unsized5.stderr @@ -6,7 +6,7 @@ LL | struct S1 { LL | f1: X, | ^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: only the last field of a struct may have a dynamically sized type @@ -19,7 +19,7 @@ LL | f: isize, LL | g: X, | ^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: only the last field of a struct may have a dynamically sized type @@ -51,7 +51,7 @@ LL | enum E { LL | V1(X, isize), | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: no field of an enum variant may have a dynamically sized type @@ -63,7 +63,7 @@ LL | enum F { LL | V2{f1: X, f: isize}, | ^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: no field of an enum variant may have a dynamically sized type diff --git a/src/test/ui/unsized6.stderr b/src/test/ui/unsized6.stderr index 337afd2ee7e10..0d288f650c026 100644 --- a/src/test/ui/unsized6.stderr +++ b/src/test/ui/unsized6.stderr @@ -7,7 +7,7 @@ LL | fn f1(x: &X) { LL | let y: Y; | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `Y` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature @@ -21,7 +21,7 @@ LL | let _: W; // <-- this is OK, no bindings created, no initializer. LL | let _: (isize, (X, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: only the last element of a tuple may have a dynamically sized type @@ -34,7 +34,7 @@ LL | fn f1(x: &X) { LL | let y: (isize, (Z, usize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `Z` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: only the last element of a tuple may have a dynamically sized type @@ -46,7 +46,7 @@ LL | fn f2(x: &X) { LL | let y: X; | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature @@ -60,7 +60,7 @@ LL | fn f2(x: &X) { LL | let y: (isize, (Y, isize)); | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `Y` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: only the last element of a tuple may have a dynamically sized type @@ -72,7 +72,7 @@ LL | fn f3(x1: Box, x2: Box, x3: Box) { LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature @@ -86,7 +86,7 @@ LL | fn f3(x1: Box, x2: Box, x3: Box) { LL | let y = *x2; | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature @@ -100,7 +100,7 @@ LL | fn f3(x1: Box, x2: Box, x3: Box) { LL | let (y, z) = (*x3, 4); | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature @@ -113,7 +113,7 @@ LL | fn f4(x1: Box, x2: Box, x3: Box) { LL | let y: X = *x1; | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature @@ -127,7 +127,7 @@ LL | fn f4(x1: Box, x2: Box, x3: Box) { LL | let y = *x2; | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature @@ -141,7 +141,7 @@ LL | fn f4(x1: Box, x2: Box, x3: Box) { LL | let (y, z) = (*x3, 4); | ^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature @@ -154,7 +154,7 @@ LL | fn g1(x: X) {} | | | this type parameter needs to be `std::marker::Sized` | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature @@ -167,7 +167,7 @@ LL | fn g2(x: X) {} | | | this type parameter needs to be `std::marker::Sized` | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature diff --git a/src/test/ui/unsized7.stderr b/src/test/ui/unsized7.stderr index 0f71c5f6f8fe6..6a9108fc05ffa 100644 --- a/src/test/ui/unsized7.stderr +++ b/src/test/ui/unsized7.stderr @@ -6,7 +6,7 @@ LL | impl T1 for S3 { | | | this type parameter needs to be `std::marker::Sized` | - = help: the trait `std::marker::Sized` is not implemented for `X` + = help: type parameters have an implicit `Sized` requirement by default = note: to learn more, visit error: aborting due to previous error From eb1ab8f00caa90e53d9042960d8e6e997c576394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 6 Mar 2020 15:47:08 -0800 Subject: [PATCH 2/2] review comments --- src/librustc/ty/sty.rs | 8 -------- src/librustc_infer/traits/error_reporting/mod.rs | 2 +- src/librustc_infer/traits/error_reporting/suggestions.rs | 6 ++++-- src/librustc_typeck/collect/type_of.rs | 2 +- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 0762977a5233c..ab2c98c89b4e6 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1927,14 +1927,6 @@ impl<'tcx> TyS<'tcx> { } } - #[inline] - pub fn is_some_param(&self) -> bool { - match self.kind { - ty::Param(_) => true, - _ => false, - } - } - #[inline] pub fn is_slice(&self) -> bool { match self.kind { diff --git a/src/librustc_infer/traits/error_reporting/mod.rs b/src/librustc_infer/traits/error_reporting/mod.rs index 8f1d9d9989d25..927d5f94892cb 100644 --- a/src/librustc_infer/traits/error_reporting/mod.rs +++ b/src/librustc_infer/traits/error_reporting/mod.rs @@ -591,7 +591,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } else if self.tcx.lang_items().sized_trait().map_or(false, |sized_id| { let self_ty = trait_ref.self_ty(); sized_id == trait_ref.def_id() - && self_ty.is_some_param() + && matches!(self_ty.kind, ty::Param(_)) && self_ty != self.tcx.types.self_param }) { // Detect type parameters with an implied `Sized` bound and explain diff --git a/src/librustc_infer/traits/error_reporting/suggestions.rs b/src/librustc_infer/traits/error_reporting/suggestions.rs index 90cca7d28a388..2ee877e6b654d 100644 --- a/src/librustc_infer/traits/error_reporting/suggestions.rs +++ b/src/librustc_infer/traits/error_reporting/suggestions.rs @@ -64,7 +64,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { generics, kind: hir::TraitItemKind::Method(..), .. - }) if self_ty.is_some_param() && self_ty == self.tcx.types.self_param => { + }) if matches!(self_ty.kind, ty::Param(_)) + && self_ty == self.tcx.types.self_param => + { // Restricting `Self` for a single method. suggest_restriction(&generics, "`Self`", err); return; @@ -138,7 +140,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }) | hir::Node::TraitItem(hir::TraitItem { generics, span, .. }) | hir::Node::ImplItem(hir::ImplItem { generics, span, .. }) - if self_ty.is_some_param() => + if matches!(self_ty.kind, ty::Param(_)) => { // Missing generic type parameter bound. let param_name = self_ty.to_string(); diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 9125329fe1529..af955110da450 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -446,7 +446,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { .filter_map(|(i, k)| { if let GenericArgKind::Type(ty) = k.unpack() { Some((i, ty)) } else { None } }) - .filter(|(_, ty)| !ty.is_some_param()) + .filter(|(_, ty)| !matches!(ty.kind, ty::Param(_))) .collect(); if !bad_substs.is_empty() { let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id);