When trait bounds are missing for return values, point at them
This commit is contained in:
parent
b4bbe784a9
commit
e1dd8a9095
11 changed files with 147 additions and 54 deletions
|
|
@ -1130,6 +1130,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
};
|
||||
|
||||
self.note_obligation_cause(&mut err, obligation);
|
||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
|
@ -1737,35 +1738,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
// Recursively look for `TraitObject` types and if there's only one, use that span to
|
||||
// suggest `impl Trait`.
|
||||
|
||||
struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>);
|
||||
|
||||
impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
|
||||
type Map = rustc::hir::map::Map<'v>;
|
||||
|
||||
fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> {
|
||||
hir::intravisit::NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
|
||||
match ex.kind {
|
||||
hir::ExprKind::Ret(Some(ex)) => self.0.push(ex),
|
||||
_ => {}
|
||||
}
|
||||
hir::intravisit::walk_expr(self, ex);
|
||||
}
|
||||
|
||||
fn visit_body(&mut self, body: &'v hir::Body<'v>) {
|
||||
if body.generator_kind().is_none() {
|
||||
if let hir::ExprKind::Block(block, None) = body.value.kind {
|
||||
if let Some(expr) = block.expr {
|
||||
self.0.push(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::intravisit::walk_body(self, body);
|
||||
}
|
||||
}
|
||||
|
||||
// Visit to make sure there's a single `return` type to suggest `impl Trait`,
|
||||
// otherwise suggest using `Box<dyn Trait>` or an enum.
|
||||
let mut visitor = ReturnsVisitor(vec![]);
|
||||
|
|
@ -1893,6 +1865,38 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
false
|
||||
}
|
||||
|
||||
fn point_at_returns_when_relevant(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) {
|
||||
if let ObligationCauseCode::SizedReturnType = obligation.cause.code.peel_derives() {
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
let hir = self.tcx.hir();
|
||||
let parent_node = hir.get_parent_node(obligation.cause.body_id);
|
||||
let node = hir.find(parent_node);
|
||||
if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) =
|
||||
node
|
||||
{
|
||||
let body = hir.body(*body_id);
|
||||
// Point at all the `return`s in the function as they have failed trait bounds.
|
||||
let mut visitor = ReturnsVisitor(vec![]);
|
||||
visitor.visit_body(&body);
|
||||
let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap();
|
||||
for expr in &visitor.0 {
|
||||
if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) {
|
||||
err.span_label(
|
||||
expr.span,
|
||||
&format!("this returned value is of type `{}`", returned_ty),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Given some node representing a fn-like thing in the HIR map,
|
||||
/// returns a span and `ArgKind` information that describes the
|
||||
/// arguments it expects. This can be supplied to
|
||||
|
|
@ -2911,19 +2915,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
ObligationCauseCode::RepeatVec(suggest_const_in_array_repeat_expressions) => {
|
||||
err.note(
|
||||
"the `Copy` trait is required because the \
|
||||
repeated element will be copied",
|
||||
"the `Copy` trait is required because the repeated element will be copied",
|
||||
);
|
||||
if suggest_const_in_array_repeat_expressions {
|
||||
err.note(
|
||||
"this array initializer can be evaluated at compile-time, for more \
|
||||
information, see issue \
|
||||
https://github.com/rust-lang/rust/issues/49147",
|
||||
information, see issue \
|
||||
https://github.com/rust-lang/rust/issues/49147",
|
||||
);
|
||||
if tcx.sess.opts.unstable_features.is_nightly_build() {
|
||||
err.help(
|
||||
"add `#![feature(const_in_array_repeat_expressions)]` to the \
|
||||
crate attributes to enable",
|
||||
crate attributes to enable",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -2941,16 +2944,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
ObligationCauseCode::SizedReturnType => {
|
||||
err.note(
|
||||
"the return type of a function must have a \
|
||||
statically known size",
|
||||
);
|
||||
err.note("the return type of a function must have a statically known size");
|
||||
}
|
||||
ObligationCauseCode::SizedYieldType => {
|
||||
err.note(
|
||||
"the yield type of a generator must have a \
|
||||
statically known size",
|
||||
);
|
||||
err.note("the yield type of a generator must have a statically known size");
|
||||
}
|
||||
ObligationCauseCode::AssignmentLhsSized => {
|
||||
err.note("the left-hand-side of an assignment must have a statically known size");
|
||||
|
|
@ -2966,12 +2963,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
if last {
|
||||
err.note(
|
||||
"the last field of a packed struct may only have a \
|
||||
dynamically sized type if it does not need drop to be run",
|
||||
dynamically sized type if it does not need drop to be run",
|
||||
);
|
||||
} else {
|
||||
err.note(
|
||||
"only the last field of a struct may have a dynamically \
|
||||
sized type",
|
||||
"only the last field of a struct may have a dynamically sized type",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -3025,13 +3021,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
ObligationCauseCode::CompareImplMethodObligation { .. } => {
|
||||
err.note(&format!(
|
||||
"the requirement `{}` appears on the impl method \
|
||||
but not on the corresponding trait method",
|
||||
but not on the corresponding trait method",
|
||||
predicate
|
||||
));
|
||||
}
|
||||
ObligationCauseCode::CompareImplTypeObligation { .. } => {
|
||||
err.note(&format!(
|
||||
"the requirement `{}` appears on the associated impl type\
|
||||
"the requirement `{}` appears on the associated impl type \
|
||||
but not on the corresponding associated trait type",
|
||||
predicate
|
||||
));
|
||||
|
|
@ -3043,8 +3039,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
err.help("see issue #48214");
|
||||
if tcx.sess.opts.unstable_features.is_nightly_build() {
|
||||
err.help(
|
||||
"add `#![feature(trivial_bounds)]` to the \
|
||||
crate attributes to enable",
|
||||
"add `#![feature(trivial_bounds)]` to the crate attributes to enable",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -3186,3 +3181,32 @@ pub fn suggest_constraining_type_param(
|
|||
}
|
||||
false
|
||||
}
|
||||
|
||||
struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>);
|
||||
|
||||
impl<'v> Visitor<'v> for ReturnsVisitor<'v> {
|
||||
type Map = rustc::hir::map::Map<'v>;
|
||||
|
||||
fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> {
|
||||
hir::intravisit::NestedVisitorMap::None
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
|
||||
match ex.kind {
|
||||
hir::ExprKind::Ret(Some(ex)) => self.0.push(ex),
|
||||
_ => {}
|
||||
}
|
||||
hir::intravisit::walk_expr(self, ex);
|
||||
}
|
||||
|
||||
fn visit_body(&mut self, body: &'v hir::Body<'v>) {
|
||||
if body.generator_kind().is_none() {
|
||||
if let hir::ExprKind::Block(block, None) = body.value.kind {
|
||||
if let Some(expr) = block.expr {
|
||||
self.0.push(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::intravisit::walk_body(self, body);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,17 @@
|
|||
error: future cannot be sent between threads safely
|
||||
--> $DIR/issue-64130-4-async-move.rs:15:17
|
||||
|
|
||||
LL | pub fn foo() -> impl Future + Send {
|
||||
| ^^^^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
|
||||
LL | pub fn foo() -> impl Future + Send {
|
||||
| ^^^^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
|
||||
...
|
||||
LL | / async move {
|
||||
LL | | match client.status() {
|
||||
LL | | 200 => {
|
||||
LL | | let _x = get().await;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____- this returned value is of type `impl std::future::Future`
|
||||
|
|
||||
= help: the trait `std::marker::Sync` is not implemented for `(dyn std::any::Any + std::marker::Send + 'static)`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_vec_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
|
||||
...
|
||||
LL | Vec::<A>::new()
|
||||
| --------------- this returned value is of type `std::vec::Vec<A>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::vec::Vec<A>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -12,6 +15,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
|
||||
...
|
||||
LL | Vec::<A>::new()
|
||||
| --------------- this returned value is of type `std::vec::Vec<A>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::vec::Vec<A>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -21,6 +27,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_vecdeque_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
|
||||
...
|
||||
LL | VecDeque::<A>::new()
|
||||
| -------------------- this returned value is of type `std::collections::VecDeque<A>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::collections::VecDeque<A>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -30,6 +39,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
|
||||
...
|
||||
LL | VecDeque::<A>::new()
|
||||
| -------------------- this returned value is of type `std::collections::VecDeque<A>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::collections::VecDeque<A>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -39,6 +51,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]>
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
|
||||
...
|
||||
LL | VecDeque::<A>::new()
|
||||
| -------------------- this returned value is of type `std::collections::VecDeque<A>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a mut [B; 33]>` for `std::collections::VecDeque<A>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_iterator() -> impl Iterator<Item = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
LL |
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::array::IntoIter<i32, 33usize>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -28,6 +31,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_double_ended_iterator() -> impl DoubleEndedIterator {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
LL |
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::iter::DoubleEndedIterator` for `std::array::IntoIter<i32, 33usize>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -45,6 +51,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_exact_size_iterator() -> impl ExactSizeIterator {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
LL |
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::iter::ExactSizeIterator` for `std::array::IntoIter<i32, 33usize>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -62,6 +71,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_fused_iterator() -> impl FusedIterator {
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
LL |
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::iter::FusedIterator` for `std::array::IntoIter<i32, 33usize>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -79,6 +91,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_trusted_len() -> impl TrustedLen {
|
||||
| ^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
LL |
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::iter::TrustedLen` for `std::array::IntoIter<i32, 33usize>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -96,6 +111,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_clone() -> impl Clone {
|
||||
| ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
LL |
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::array::IntoIter<i32, 33usize>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -113,6 +131,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
|||
|
|
||||
LL | pub fn no_debug() -> impl Debug {
|
||||
| ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
LL |
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::fmt::Debug` for `std::array::IntoIter<i32, 33usize>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ LL | type C where Self: Copy = String;
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `std::marker::Copy` for `Fooy<T>`
|
||||
= note: the requirement `Fooy<T>: std::marker::Copy` appears on the associated impl typebut not on the corresponding associated trait type
|
||||
= note: the requirement `Fooy<T>: std::marker::Copy` appears on the associated impl type but not on the corresponding associated trait type
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be know
|
|||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13
|
||||
|
|
||||
LL | fn fuz() -> (usize, Trait) { (42, Struct) }
|
||||
| ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))`
|
||||
| |
|
||||
| doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)`
|
||||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
|
|
@ -31,7 +33,9 @@ error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be know
|
|||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13
|
||||
|
|
||||
LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
|
||||
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))`
|
||||
| |
|
||||
| doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)`
|
||||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ error[E0277]: the trait bound `impl Trait<<u32 as std::ops::Add>::Output>: Trait
|
|||
|
|
||||
LL | ) -> Either<impl Trait<<u32 as Add<u32>>::Output>, impl Trait<<u32 as Add<u32>>::Output>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<u32>` is not implemented for `impl Trait<<u32 as std::ops::Add>::Output>`
|
||||
...
|
||||
LL | add_generic(value, 1u32)
|
||||
| ------------------------ this returned value is of type `Either<impl Trait<<_ as std::ops::Add<_>>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>`
|
||||
|
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
|
|
@ -11,6 +14,9 @@ error[E0277]: the trait bound `impl Trait<<u32 as std::ops::Add>::Output>: Trait
|
|||
|
|
||||
LL | ) -> Either<impl Trait<<u32 as Add<u32>>::Output>, impl Trait<<u32 as Add<u32>>::Output>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<u32>` is not implemented for `impl Trait<<u32 as std::ops::Add>::Output>`
|
||||
...
|
||||
LL | add_generic(value, 1u32)
|
||||
| ------------------------ this returned value is of type `Either<impl Trait<<_ as std::ops::Add<_>>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>`
|
||||
|
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at
|
|||
|
|
||||
LL | -> Struct {
|
||||
| ^^^^^^ doesn't have a size known at compile-time
|
||||
LL |
|
||||
LL | Struct { r: r }
|
||||
| --------------- this returned value is of type `Struct`
|
||||
|
|
||||
= help: within `Struct`, the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)`
|
||||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ error[E0277]: the trait bound `std::result::Result<(), _>: Future` is not satisf
|
|||
|
|
||||
LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `std::result::Result<(), _>`
|
||||
LL |
|
||||
LL | Ok(())
|
||||
| ------ this returned value is of type `std::result::Result<_, _>`
|
||||
|
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,12 @@ error[E0277]: the trait bound `(): T` is not satisfied
|
|||
|
|
||||
LL | fn should_ret_unit() -> impl T {
|
||||
| ^^^^^^ the trait `T` is not implemented for `()`
|
||||
LL |
|
||||
LL | panic!()
|
||||
| -------- this returned value is of type `_`
|
||||
|
|
||||
= note: the return type of a function must have a statically known size
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ LL | type Underconstrained<T: std::fmt::Debug> = impl 'static;
|
|||
...
|
||||
LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
|
||||
| - help: consider restricting this bound: `U: std::fmt::Debug`
|
||||
LL | 5u32
|
||||
| ---- this returned value is of type `u32`
|
||||
|
|
||||
= help: the trait `std::fmt::Debug` is not implemented for `U`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
@ -30,6 +32,8 @@ LL | type Underconstrained2<T: std::fmt::Debug> = impl 'static;
|
|||
...
|
||||
LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
|
||||
| - help: consider restricting this bound: `V: std::fmt::Debug`
|
||||
LL | 5u32
|
||||
| ---- this returned value is of type `u32`
|
||||
|
|
||||
= help: the trait `std::fmt::Debug` is not implemented for `V`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue