Use root obligation on E0277 for some cases
When encountering trait bound errors that satisfy some heuristics that tell us that the relevant trait for the user comes from the root obligation and not the current obligation, we use the root predicate for the main message. This allows to talk about "X doesn't implement Pattern<'_>" over the most specific case that just happened to fail, like "char doesn't implement Fn(&mut char)" in `tests/ui/traits/suggest-dereferences/root-obligation.rs` The heuristics are: - the type of the leaf predicate is (roughly) the same as the type from the root predicate, as a proxy for "we care about the root" - the leaf trait and the root trait are different, so as to avoid talking about `&mut T: Trait` and instead remain talking about `T: Trait` instead - the root trait is not `Unsize`, as to avoid talking about it in `tests/ui/coercion/coerce-issue-49593-box-never.rs`. ``` error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied --> $DIR/root-obligation.rs:6:38 | LL | .filter(|c| "aeiou".contains(c)) | -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>` | | | required by a bound introduced by this call | = note: required for `&char` to implement `FnOnce<(char,)>` = note: required for `&char` to implement `Pattern<'_>` note: required by a bound in `core::str::<impl str>::contains` --> $SRC_DIR/core/src/str/mod.rs:LL:COL help: consider dereferencing here | LL | .filter(|c| "aeiou".contains(*c)) | + ``` Fix #79359, fix #119983, fix #118779, cc #118415 (the suggestion needs to change).
This commit is contained in:
parent
26907374b9
commit
f0c93117ed
49 changed files with 166 additions and 120 deletions
|
@ -416,9 +416,51 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
|
||||
let trait_predicate = bound_predicate.rebind(trait_predicate);
|
||||
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
|
||||
let trait_ref = trait_predicate.to_poly_trait_ref();
|
||||
|
||||
if let Some(guar) = self.emit_specialized_closure_kind_error(&obligation, trait_ref) {
|
||||
// Let's use the root obligation as the main message, when we care about the
|
||||
// most general case ("X doesn't implement Pattern<'_>") over the case that
|
||||
// happened to fail ("char doesn't implement Fn(&mut char)").
|
||||
//
|
||||
// We rely on a few heuristics to identify cases where this root
|
||||
// obligation is more important than the leaf obligation:
|
||||
let (main_trait_predicate, o) = if let ty::PredicateKind::Clause(
|
||||
ty::ClauseKind::Trait(root_pred)
|
||||
) = root_obligation.predicate.kind().skip_binder()
|
||||
// The type of the leaf predicate is (roughly) the same as the type
|
||||
// from the root predicate, as a proxy for "we care about the root"
|
||||
// FIXME: this doesn't account for trivial derefs, but works as a first
|
||||
// approximation.
|
||||
&& (
|
||||
// `T: Trait` && `&&T: OtherTrait`, we want `OtherTrait`
|
||||
trait_predicate.self_ty().skip_binder()
|
||||
== root_pred.self_ty().peel_refs()
|
||||
// `&str: Iterator` && `&str: IntoIterator`, we want `IntoIterator`
|
||||
|| trait_predicate.self_ty().skip_binder()
|
||||
== root_pred.self_ty()
|
||||
)
|
||||
// The leaf trait and the root trait are different, so as to avoid
|
||||
// talking about `&mut T: Trait` and instead remain talking about
|
||||
// `T: Trait` instead
|
||||
&& trait_predicate.def_id() != root_pred.def_id()
|
||||
// The root trait is not `Unsize`, as to avoid talking about it in
|
||||
// `tests/ui/coercion/coerce-issue-49593-box-never.rs`.
|
||||
&& Some(root_pred.def_id()) != self.tcx.lang_items().unsize_trait()
|
||||
{
|
||||
(
|
||||
self.resolve_vars_if_possible(
|
||||
root_obligation.predicate.kind().rebind(root_pred),
|
||||
),
|
||||
root_obligation,
|
||||
)
|
||||
} else {
|
||||
(trait_predicate, &obligation)
|
||||
};
|
||||
let trait_ref = main_trait_predicate.to_poly_trait_ref();
|
||||
|
||||
if let Some(guar) = self.emit_specialized_closure_kind_error(
|
||||
&obligation,
|
||||
trait_ref,
|
||||
) {
|
||||
return guar;
|
||||
}
|
||||
|
||||
|
@ -459,8 +501,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
notes,
|
||||
parent_label,
|
||||
append_const_msg,
|
||||
} = self.on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file);
|
||||
|
||||
} = self.on_unimplemented_note(trait_ref, o, &mut long_ty_file);
|
||||
let have_alt_message = message.is_some() || label.is_some();
|
||||
let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id());
|
||||
let is_unsize =
|
||||
|
@ -483,7 +524,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
};
|
||||
|
||||
let err_msg = self.get_standard_error_message(
|
||||
&trait_predicate,
|
||||
&main_trait_predicate,
|
||||
message,
|
||||
predicate_is_const,
|
||||
append_const_msg,
|
||||
|
|
|
@ -30,8 +30,7 @@ use crate::task::{Context, Poll};
|
|||
#[lang = "future_trait"]
|
||||
#[diagnostic::on_unimplemented(
|
||||
label = "`{Self}` is not a future",
|
||||
message = "`{Self}` is not a future",
|
||||
note = "{Self} must be a future or must implement `IntoFuture` to be awaited"
|
||||
message = "`{Self}` is not a future"
|
||||
)]
|
||||
pub trait Future {
|
||||
/// The type of value produced on completion.
|
||||
|
|
|
@ -100,6 +100,11 @@ use crate::future::Future;
|
|||
/// ```
|
||||
#[stable(feature = "into_future", since = "1.64.0")]
|
||||
#[rustc_diagnostic_item = "IntoFuture"]
|
||||
#[diagnostic::on_unimplemented(
|
||||
label = "`{Self}` is not a future",
|
||||
message = "`{Self}` is not a future",
|
||||
note = "{Self} must be a future or must implement `IntoFuture` to be awaited"
|
||||
)]
|
||||
pub trait IntoFuture {
|
||||
/// The output that the future will produce on completion.
|
||||
#[stable(feature = "into_future", since = "1.64.0")]
|
||||
|
|
|
@ -236,6 +236,49 @@ pub trait FromIterator<A>: Sized {
|
|||
/// ```
|
||||
#[rustc_diagnostic_item = "IntoIterator"]
|
||||
#[rustc_skip_array_during_method_dispatch]
|
||||
#[rustc_on_unimplemented(
|
||||
on(
|
||||
_Self = "core::ops::range::RangeTo<Idx>",
|
||||
label = "if you meant to iterate until a value, add a starting value",
|
||||
note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \
|
||||
bounded `Range`: `0..end`"
|
||||
),
|
||||
on(
|
||||
_Self = "core::ops::range::RangeToInclusive<Idx>",
|
||||
label = "if you meant to iterate until a value (including it), add a starting value",
|
||||
note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \
|
||||
to have a bounded `RangeInclusive`: `0..=end`"
|
||||
),
|
||||
on(
|
||||
_Self = "[]",
|
||||
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
|
||||
),
|
||||
on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"),
|
||||
on(
|
||||
_Self = "alloc::vec::Vec<T, A>",
|
||||
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
|
||||
),
|
||||
on(
|
||||
_Self = "&str",
|
||||
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
|
||||
),
|
||||
on(
|
||||
_Self = "alloc::string::String",
|
||||
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
|
||||
),
|
||||
on(
|
||||
_Self = "{integral}",
|
||||
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
|
||||
syntax `start..end` or the inclusive range syntax `start..=end`"
|
||||
),
|
||||
on(
|
||||
_Self = "{float}",
|
||||
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
|
||||
syntax `start..end` or the inclusive range syntax `start..=end`"
|
||||
),
|
||||
label = "`{Self}` is not an iterator",
|
||||
message = "`{Self}` is not an iterator"
|
||||
)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait IntoIterator {
|
||||
/// The type of the elements being iterated over.
|
||||
|
|
|
@ -28,15 +28,11 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
|||
#[rustc_on_unimplemented(
|
||||
on(
|
||||
_Self = "core::ops::range::RangeTo<Idx>",
|
||||
label = "if you meant to iterate until a value, add a starting value",
|
||||
note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \
|
||||
bounded `Range`: `0..end`"
|
||||
note = "you might have meant to use a bounded `Range`"
|
||||
),
|
||||
on(
|
||||
_Self = "core::ops::range::RangeToInclusive<Idx>",
|
||||
label = "if you meant to iterate until a value (including it), add a starting value",
|
||||
note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \
|
||||
to have a bounded `RangeInclusive`: `0..=end`"
|
||||
note = "you might have meant to use a bounded `RangeInclusive`"
|
||||
),
|
||||
on(
|
||||
_Self = "[]",
|
||||
|
@ -47,24 +43,6 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
|||
_Self = "alloc::vec::Vec<T, A>",
|
||||
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
|
||||
),
|
||||
on(
|
||||
_Self = "&str",
|
||||
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
|
||||
),
|
||||
on(
|
||||
_Self = "alloc::string::String",
|
||||
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
|
||||
),
|
||||
on(
|
||||
_Self = "{integral}",
|
||||
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
|
||||
syntax `start..end` or the inclusive range syntax `start..=end`"
|
||||
),
|
||||
on(
|
||||
_Self = "{float}",
|
||||
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
|
||||
syntax `start..end` or the inclusive range syntax `start..=end`"
|
||||
),
|
||||
label = "`{Self}` is not an iterator",
|
||||
message = "`{Self}` is not an iterator"
|
||||
)]
|
||||
|
|
|
@ -70,13 +70,12 @@ help: use parentheses to call this function
|
|||
LL | let x: () = foo::<'static>();
|
||||
| ++
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
error[E0277]: the trait bound `str: Foo<'_, '_, u8>` is not satisfied
|
||||
--> $DIR/substs-ppaux.rs:49:6
|
||||
|
|
||||
LL | <str as Foo<u8>>::bar;
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
| ^^^ the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'_, '_, u8>`
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'_, '_, u8>`
|
||||
note: required for `str` to implement `Foo<'_, '_, u8>`
|
||||
--> $DIR/substs-ppaux.rs:11:17
|
||||
|
|
||||
|
|
|
@ -47,6 +47,6 @@ fn foo<'z>() where &'z (): Sized {
|
|||
//[normal]~| found fn item `fn() {foo::<'static>}`
|
||||
|
||||
<str as Foo<u8>>::bar;
|
||||
//[verbose]~^ ERROR the size for values of type
|
||||
//[normal]~^^ ERROR the size for values of type
|
||||
//[verbose]~^ ERROR the trait bound `str: Foo<'?0, '?1, u8>` is not satisfied
|
||||
//[normal]~^^ ERROR the trait bound `str: Foo<'_, '_, u8>` is not satisfied
|
||||
}
|
||||
|
|
|
@ -70,13 +70,12 @@ help: use parentheses to call this function
|
|||
LL | let x: () = foo::<'static>();
|
||||
| ++
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
error[E0277]: the trait bound `str: Foo<'?0, '?1, u8>` is not satisfied
|
||||
--> $DIR/substs-ppaux.rs:49:6
|
||||
|
|
||||
LL | <str as Foo<u8>>::bar;
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
| ^^^ the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'?0, '?1, u8>`
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'?0, '?1, u8>`
|
||||
note: required for `str` to implement `Foo<'?0, '?1, u8>`
|
||||
--> $DIR/substs-ppaux.rs:11:17
|
||||
|
|
||||
|
|
|
@ -5,7 +5,6 @@ LL | fn get_future() -> impl Future<Output = ()> {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `()`
|
||||
= note: () must be a future or must implement `IntoFuture` to be awaited
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/async-error-span.rs:13:9
|
||||
|
|
|
@ -49,7 +49,6 @@ LL | takes_future(returns_coroutine());
|
|||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `impl Coroutine<Yield = (), Return = ()>`
|
||||
= note: impl Coroutine<Yield = (), Return = ()> must be a future or must implement `IntoFuture` to be awaited
|
||||
note: required by a bound in `takes_future`
|
||||
--> $DIR/coroutine-not-future.rs:17:26
|
||||
|
|
||||
|
@ -69,7 +68,6 @@ LL | | });
|
|||
| |_____^ `{coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23}` is not a future
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `{coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23}`
|
||||
= note: {coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23} must be a future or must implement `IntoFuture` to be awaited
|
||||
note: required by a bound in `takes_future`
|
||||
--> $DIR/coroutine-not-future.rs:17:26
|
||||
|
|
||||
|
|
|
@ -17,5 +17,5 @@ impl Signed for i32 { }
|
|||
fn main() {
|
||||
is_defaulted::<&'static i32>();
|
||||
is_defaulted::<&'static u32>();
|
||||
//~^ ERROR `u32: Signed` is not satisfied
|
||||
//~^ ERROR the trait bound `&'static u32: Defaulted` is not satisfied
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the trait bound `u32: Signed` is not satisfied
|
||||
error[E0277]: the trait bound `&'static u32: Defaulted` is not satisfied
|
||||
--> $DIR/typeck-default-trait-impl-precedence.rs:19:20
|
||||
|
|
||||
LL | is_defaulted::<&'static u32>();
|
||||
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`, which is required by `&'static u32: Defaulted`
|
||||
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `&'static u32`, which is required by `&'static u32: Defaulted`
|
||||
|
|
||||
note: required for `&'static u32` to implement `Defaulted`
|
||||
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19
|
||||
|
|
|
@ -5,7 +5,6 @@ LL | fn foo() -> impl std::future::Future {
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}` is not a future
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}`
|
||||
= note: {gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21} must be a future or must implement `IntoFuture` to be awaited
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@ LL | fn use_for() where i32: Iterator {
|
|||
| ^^^^^^^^^^^^^ `i32` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `i32`
|
||||
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
|
||||
= help: see issue #48214
|
||||
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0277]: the size for values of type `dyn Iterator<Item = &'a mut u8>` cannot be known at compilation time
|
||||
error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
||||
--> $DIR/issue-20605.rs:5:17
|
||||
|
|
||||
LL | for item in *things { *item = 0 }
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
error[E0277]: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
|
||||
error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
||||
--> $DIR/issue-20605.rs:5:17
|
||||
|
|
||||
LL | for item in *things { *item = 0 }
|
||||
| ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
| ^^^^^^^ `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
||||
|
|
||||
= help: the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
|
||||
|
||||
error: the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
||||
--> $DIR/issue-20605.rs:5:17
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
|
||||
for item in *things { *item = 0 }
|
||||
//[current]~^ ERROR the size for values of type
|
||||
//[next]~^^ ERROR the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
|
||||
//[current]~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
||||
//[next]~^^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
||||
//[next]~| ERROR the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
||||
//[next]~| ERROR the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
|
||||
//[next]~| ERROR the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed
|
||||
|
|
|
@ -5,7 +5,6 @@ LL | fn get_fut(&self) -> Self::Fut {
|
|||
| ^^^^^^^^^ `{integer}` is not a future
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `{integer}`
|
||||
= note: {integer} must be a future or must implement `IntoFuture` to be awaited
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ LL | *x
|
|||
| -- return type was inferred to be `u32` here
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `u32`
|
||||
= note: u32 must be a future or must implement `IntoFuture` to be awaited
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ LL | struct T(S<u8>);
|
|||
| ^^^^^ `u8` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `u8`
|
||||
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
|
||||
note: required by a bound in `S`
|
||||
--> $DIR/bound.rs:1:13
|
||||
|
|
||||
|
|
|
@ -11,5 +11,5 @@ fn take_param<T:Foo>(foo: &T) { }
|
|||
fn main() {
|
||||
let x: Box<_> = Box::new(3);
|
||||
take_param(&x);
|
||||
//~^ ERROR the trait bound `Box<{integer}>: Copy` is not satisfied
|
||||
//~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
|
||||
error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
|
||||
--> $DIR/kindck-impl-type-params-2.rs:13:16
|
||||
|
|
||||
LL | take_param(&x);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
|
||||
error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
|
||||
--> $DIR/kindck-inherited-copy-bound.rs:21:16
|
||||
|
|
||||
LL | take_param(&x);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
|
||||
error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
|
||||
--> $DIR/kindck-inherited-copy-bound.rs:21:16
|
||||
|
|
||||
LL | take_param(&x);
|
||||
|
|
|
@ -10,7 +10,7 @@ trait Message : Send { }
|
|||
|
||||
fn object_ref_with_static_bound_not_ok() {
|
||||
assert_send::<&'static (dyn Dummy + 'static)>();
|
||||
//~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
|
||||
//~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277]
|
||||
}
|
||||
|
||||
fn box_object_with_no_bound_not_ok<'a>() {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
|
||||
error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
||||
--> $DIR/kindck-send-object.rs:12:19
|
||||
|
|
||||
LL | assert_send::<&'static (dyn Dummy + 'static)>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
|
||||
= help: the trait `Sync` is not implemented for `&'static (dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
|
||||
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
|
||||
note: required by a bound in `assert_send`
|
||||
--> $DIR/kindck-send-object.rs:5:18
|
||||
|
|
|
@ -8,7 +8,7 @@ trait Dummy { }
|
|||
// careful with object types, who knows what they close over...
|
||||
fn test51<'a>() {
|
||||
assert_send::<&'a dyn Dummy>();
|
||||
//~^ ERROR `(dyn Dummy + 'a)` cannot be shared between threads safely [E0277]
|
||||
//~^ ERROR `&'a (dyn Dummy + 'a)` cannot be sent between threads safely [E0277]
|
||||
}
|
||||
fn test52<'a>() {
|
||||
assert_send::<&'a (dyn Dummy + Sync)>();
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely
|
||||
error[E0277]: `&'a (dyn Dummy + 'a)` cannot be sent between threads safely
|
||||
--> $DIR/kindck-send-object1.rs:10:19
|
||||
|
|
||||
LL | assert_send::<&'a dyn Dummy>();
|
||||
| ^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
|
||||
| ^^^^^^^^^^^^^ `&'a (dyn Dummy + 'a)` cannot be sent between threads safely
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)`, which is required by `&'a (dyn Dummy + 'a): Send`
|
||||
= help: the trait `Sync` is not implemented for `&'a (dyn Dummy + 'a)`, which is required by `&'a (dyn Dummy + 'a): Send`
|
||||
= note: required for `&'a (dyn Dummy + 'a)` to implement `Send`
|
||||
note: required by a bound in `assert_send`
|
||||
--> $DIR/kindck-send-object1.rs:5:18
|
||||
|
|
|
@ -5,7 +5,7 @@ trait Dummy { }
|
|||
|
||||
fn test50() {
|
||||
assert_send::<&'static dyn Dummy>();
|
||||
//~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
|
||||
//~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277]
|
||||
}
|
||||
|
||||
fn test53() {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
|
||||
error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
||||
--> $DIR/kindck-send-object2.rs:7:19
|
||||
|
|
||||
LL | assert_send::<&'static dyn Dummy>();
|
||||
| ^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
|
||||
| ^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
|
||||
= help: the trait `Sync` is not implemented for `&'static (dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
|
||||
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
|
||||
note: required by a bound in `assert_send`
|
||||
--> $DIR/kindck-send-object2.rs:3:18
|
||||
|
|
|
@ -17,5 +17,5 @@ fn stuff<T: Bar>(_: T) {}
|
|||
|
||||
fn main() {
|
||||
stuff(1u8);
|
||||
//~^ the trait bound `u8: Foo` is not satisfied
|
||||
//~^ the trait bound `u8: Bar` is not satisfied
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0277]: the trait bound `u8: Foo` is not satisfied
|
||||
error[E0277]: the trait bound `u8: Bar` is not satisfied
|
||||
--> $DIR/feature-gate-do_not_recommend.rs:19:11
|
||||
|
|
||||
LL | stuff(1u8);
|
||||
|
|
|
@ -7,7 +7,6 @@ LL | bar(foo);
|
|||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Future` is not implemented for fn item `fn() -> impl Future<Output = ()> {foo}`
|
||||
= note: fn() -> impl Future<Output = ()> {foo} must be a future or must implement `IntoFuture` to be awaited
|
||||
note: required by a bound in `bar`
|
||||
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16
|
||||
|
|
||||
|
@ -27,7 +26,6 @@ LL | bar(async_closure);
|
|||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33}`
|
||||
= note: {async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33} must be a future or must implement `IntoFuture` to be awaited
|
||||
note: required by a bound in `bar`
|
||||
--> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16
|
||||
|
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
fn foo(x: &str) -> bool {
|
||||
x.starts_with(&("hi".to_string() + " you"))
|
||||
//~^ ERROR expected a `FnMut(char)` closure, found `String`
|
||||
//~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
|
||||
}
|
||||
|
||||
fn foo2(x: &str) -> bool {
|
||||
x.starts_with(&"hi".to_string())
|
||||
//~^ ERROR expected a `FnMut(char)` closure, found `String`
|
||||
//~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
fn foo(x: &str) -> bool {
|
||||
x.starts_with("hi".to_string() + " you")
|
||||
//~^ ERROR expected a `FnMut(char)` closure, found `String`
|
||||
//~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
|
||||
}
|
||||
|
||||
fn foo2(x: &str) -> bool {
|
||||
x.starts_with("hi".to_string())
|
||||
//~^ ERROR expected a `FnMut(char)` closure, found `String`
|
||||
//~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0277]: expected a `FnMut(char)` closure, found `String`
|
||||
error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied
|
||||
--> $DIR/issue-104961.rs:4:19
|
||||
|
|
||||
LL | x.starts_with("hi".to_string() + " you")
|
||||
|
@ -6,7 +6,6 @@ LL | x.starts_with("hi".to_string() + " you")
|
|||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: the trait bound `String: Pattern<'_>` is not satisfied
|
||||
= note: required for `String` to implement `Pattern<'_>`
|
||||
note: required by a bound in `core::str::<impl str>::starts_with`
|
||||
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
|
||||
|
@ -15,7 +14,7 @@ help: consider borrowing here
|
|||
LL | x.starts_with(&("hi".to_string() + " you"))
|
||||
| ++ +
|
||||
|
||||
error[E0277]: expected a `FnMut(char)` closure, found `String`
|
||||
error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied
|
||||
--> $DIR/issue-104961.rs:9:19
|
||||
|
|
||||
LL | x.starts_with("hi".to_string())
|
||||
|
@ -23,7 +22,6 @@ LL | x.starts_with("hi".to_string())
|
|||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: the trait bound `String: Pattern<'_>` is not satisfied
|
||||
= note: required for `String` to implement `Pattern<'_>`
|
||||
note: required by a bound in `core::str::<impl str>::starts_with`
|
||||
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error[E0277]: expected a `FnMut(char)` closure, found `String`
|
||||
error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied
|
||||
--> $DIR/issue-62843.rs:4:32
|
||||
|
|
||||
LL | println!("{:?}", line.find(pattern));
|
||||
|
@ -6,7 +6,6 @@ LL | println!("{:?}", line.find(pattern));
|
|||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: the trait bound `String: Pattern<'_>` is not satisfied
|
||||
= note: required for `String` to implement `Pattern<'_>`
|
||||
note: required by a bound in `core::str::<impl str>::find`
|
||||
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
fn main() {
|
||||
let v = vec![1i32, 2, 3];
|
||||
for _ in v[1..] {
|
||||
//~^ ERROR [i32]` is not an iterator [E0277]
|
||||
//~^^ ERROR known at compilation time
|
||||
//~^ ERROR `[i32]` is not an iterator [E0277]
|
||||
//~| ERROR `[i32]` is not an iterator [E0277]
|
||||
}
|
||||
struct K {
|
||||
n: i32,
|
||||
}
|
||||
let mut v2 = vec![K { n: 1 }, K { n: 1 }, K { n: 1 }];
|
||||
for i2 in v2[1..] {
|
||||
//~^ ERROR [K]` is not an iterator [E0277]
|
||||
//~^^ ERROR known at compilation time
|
||||
//~^ ERROR `[K]` is not an iterator [E0277]
|
||||
//~| ERROR `[K]` is not an iterator [E0277]
|
||||
i2.n = 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ LL | for _ in &v[1..] {
|
|||
LL | for _ in &mut v[1..] {
|
||||
| ++++
|
||||
|
||||
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||
error[E0277]: `[i32]` is not an iterator
|
||||
--> $DIR/slice-issue-87994.rs:3:12
|
||||
|
|
||||
LL | for _ in v[1..] {
|
||||
|
@ -21,6 +21,7 @@ LL | for _ in v[1..] {
|
|||
|
|
||||
= note: the trait bound `[i32]: IntoIterator` is not satisfied
|
||||
= note: required for `[i32]` to implement `IntoIterator`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | for _ in &v[1..] {
|
||||
|
@ -43,7 +44,7 @@ LL | for i2 in &v2[1..] {
|
|||
LL | for i2 in &mut v2[1..] {
|
||||
| ++++
|
||||
|
||||
error[E0277]: the size for values of type `[K]` cannot be known at compilation time
|
||||
error[E0277]: `[K]` is not an iterator
|
||||
--> $DIR/slice-issue-87994.rs:11:13
|
||||
|
|
||||
LL | for i2 in v2[1..] {
|
||||
|
@ -51,6 +52,7 @@ LL | for i2 in v2[1..] {
|
|||
|
|
||||
= note: the trait bound `[K]: IntoIterator` is not satisfied
|
||||
= note: required for `[K]` to implement `IntoIterator`
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | for i2 in &v2[1..] {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0277]: `Vec<i32>` is not an iterator
|
||||
error[E0277]: `&mut &mut &mut &mut Vec<i32>` is not an iterator
|
||||
--> $DIR/suggest-remove-refs-5.rs:4:14
|
||||
|
|
||||
LL | for _ in &mut &mut v {}
|
||||
| ^^^^^^^^^^^ `Vec<i32>` is not an iterator; try calling `.into_iter()` or `.iter()`
|
||||
| ^^^^^^^^^^^ `&mut &mut &mut &mut Vec<i32>` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `Vec<i32>`, which is required by `&mut &mut &mut &mut Vec<i32>: IntoIterator`
|
||||
= help: the trait `Iterator` is not implemented for `&mut &mut &mut &mut Vec<i32>`, which is required by `&mut &mut &mut &mut Vec<i32>: IntoIterator`
|
||||
= note: required for `&mut Vec<i32>` to implement `Iterator`
|
||||
= note: 3 redundant requirements hidden
|
||||
= note: required for `&mut &mut &mut &mut Vec<i32>` to implement `Iterator`
|
||||
|
@ -15,13 +15,13 @@ LL ~ let v = &mut Vec::<i32>::new();
|
|||
LL ~ for _ in v {}
|
||||
|
|
||||
|
||||
error[E0277]: `[u8; 1]` is not an iterator
|
||||
error[E0277]: `&mut &mut &mut [u8; 1]` is not an iterator
|
||||
--> $DIR/suggest-remove-refs-5.rs:7:14
|
||||
|
|
||||
LL | for _ in &mut v {}
|
||||
| ^^^^^^ `[u8; 1]` is not an iterator; try calling `.into_iter()` or `.iter()`
|
||||
| ^^^^^^ `&mut &mut &mut [u8; 1]` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `[u8; 1]`, which is required by `&mut &mut &mut [u8; 1]: IntoIterator`
|
||||
= help: the trait `Iterator` is not implemented for `&mut &mut &mut [u8; 1]`, which is required by `&mut &mut &mut [u8; 1]: IntoIterator`
|
||||
= note: required for `&mut [u8; 1]` to implement `Iterator`
|
||||
= note: 2 redundant requirements hidden
|
||||
= note: required for `&mut &mut &mut [u8; 1]` to implement `Iterator`
|
||||
|
|
|
@ -12,6 +12,6 @@ fn use_alias<T: SendSync>() {}
|
|||
fn main() {
|
||||
use_alias::<u32>();
|
||||
use_alias::<Rc<u32>>();
|
||||
//~^ ERROR `Rc<u32>` cannot be sent between threads safely [E0277]
|
||||
//~^^ ERROR `Rc<u32>` cannot be shared between threads safely [E0277]
|
||||
//~^ ERROR the trait bound `Rc<u32>: SendSync` is not satisfied [E0277]
|
||||
//~| ERROR the trait bound `Rc<u32>: SendSync` is not satisfied [E0277]
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
error[E0277]: `Rc<u32>` cannot be sent between threads safely
|
||||
error[E0277]: the trait bound `Rc<u32>: SendSync` is not satisfied
|
||||
--> $DIR/cross-crate.rs:14:17
|
||||
|
|
||||
LL | use_alias::<Rc<u32>>();
|
||||
| ^^^^^^^ `Rc<u32>` cannot be sent between threads safely
|
||||
| ^^^^^^^ the trait `Send` is not implemented for `Rc<u32>`, which is required by `Rc<u32>: SendSync`
|
||||
|
|
||||
= help: the trait `Send` is not implemented for `Rc<u32>`, which is required by `Rc<u32>: SendSync`
|
||||
= note: required for `Rc<u32>` to implement `SendSync`
|
||||
note: required by a bound in `use_alias`
|
||||
--> $DIR/cross-crate.rs:10:17
|
||||
|
@ -12,13 +11,12 @@ note: required by a bound in `use_alias`
|
|||
LL | fn use_alias<T: SendSync>() {}
|
||||
| ^^^^^^^^ required by this bound in `use_alias`
|
||||
|
||||
error[E0277]: `Rc<u32>` cannot be shared between threads safely
|
||||
error[E0277]: the trait bound `Rc<u32>: SendSync` is not satisfied
|
||||
--> $DIR/cross-crate.rs:14:17
|
||||
|
|
||||
LL | use_alias::<Rc<u32>>();
|
||||
| ^^^^^^^ `Rc<u32>` cannot be shared between threads safely
|
||||
| ^^^^^^^ the trait `Sync` is not implemented for `Rc<u32>`, which is required by `Rc<u32>: SendSync`
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `Rc<u32>`, which is required by `Rc<u32>: SendSync`
|
||||
= note: required for `Rc<u32>` to implement `SendSync`
|
||||
note: required by a bound in `use_alias`
|
||||
--> $DIR/cross-crate.rs:10:17
|
||||
|
|
|
@ -7,5 +7,5 @@ trait IteratorAlias = Iterator;
|
|||
fn f(_: impl IteratorAlias) {}
|
||||
|
||||
fn main() {
|
||||
f(()) //~ `()` is not an iterator
|
||||
f(()) //~ ERROR the trait bound `(): IteratorAlias` is not satisfied
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
error[E0277]: `()` is not an iterator
|
||||
error[E0277]: the trait bound `(): IteratorAlias` is not satisfied
|
||||
--> $DIR/issue-108072-unmet-trait-alias-bound.rs:10:7
|
||||
|
|
||||
LL | f(())
|
||||
| - ^^ `()` is not an iterator
|
||||
| - ^^ the trait `Iterator` is not implemented for `()`, which is required by `(): IteratorAlias`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `()`, which is required by `(): IteratorAlias`
|
||||
= note: required for `()` to implement `IteratorAlias`
|
||||
note: required by a bound in `f`
|
||||
--> $DIR/issue-108072-unmet-trait-alias-bound.rs:7:14
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | auto trait Magic: Copy {}
|
|||
| |
|
||||
| auto traits cannot have super traits or lifetime bounds
|
||||
|
||||
error[E0277]: the trait bound `NoClone: Copy` is not satisfied
|
||||
error[E0277]: the trait bound `NoClone: Magic` is not satisfied
|
||||
--> $DIR/supertrait-auto-trait.rs:16:23
|
||||
|
|
||||
LL | let (a, b) = copy(NoClone);
|
||||
|
|
|
@ -93,7 +93,6 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `i32`
|
||||
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
|
||||
|
||||
error[E0277]: `i32` is not an iterator
|
||||
--> $DIR/issue-50480.rs:14:33
|
||||
|
@ -102,7 +101,6 @@ LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `i32`
|
||||
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
|
||||
|
||||
error[E0277]: `i32` is not an iterator
|
||||
--> $DIR/issue-50480.rs:3:28
|
||||
|
@ -111,7 +109,6 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
|
|||
| ^^^ `i32` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `i32`
|
||||
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
|
||||
|
||||
error[E0277]: `i32` is not an iterator
|
||||
--> $DIR/issue-50480.rs:11:10
|
||||
|
@ -120,7 +117,6 @@ LL | #[derive(Clone, Copy)]
|
|||
| ^^^^^ `i32` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `i32`
|
||||
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
|
||||
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: `i32` is not an iterator
|
||||
|
@ -133,7 +129,6 @@ LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
|
||||
|
|
||||
= help: the trait `Iterator` is not implemented for `i32`
|
||||
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
|
||||
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
|
|
@ -4,7 +4,7 @@ fn get_vowel_count(string: &str) -> usize {
|
|||
string
|
||||
.chars()
|
||||
.filter(|c| "aeiou".contains(*c))
|
||||
//~^ ERROR expected a `Fn(char)` closure, found `char`
|
||||
//~^ ERROR the trait bound `&char: Pattern<'_>` is not satisfied
|
||||
.count()
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ fn get_vowel_count(string: &str) -> usize {
|
|||
string
|
||||
.chars()
|
||||
.filter(|c| "aeiou".contains(c))
|
||||
//~^ ERROR expected a `Fn(char)` closure, found `char`
|
||||
//~^ ERROR the trait bound `&char: Pattern<'_>` is not satisfied
|
||||
.count()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
error[E0277]: expected a `Fn(char)` closure, found `char`
|
||||
error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied
|
||||
--> $DIR/root-obligation.rs:6:38
|
||||
|
|
||||
LL | .filter(|c| "aeiou".contains(c))
|
||||
| -------- ^ expected an `Fn(char)` closure, found `char`
|
||||
| -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Fn<(char,)>` is not implemented for `char`, which is required by `&char: Pattern<'_>`
|
||||
= note: required for `&char` to implement `FnOnce<(char,)>`
|
||||
= note: required for `&char` to implement `Pattern<'_>`
|
||||
note: required by a bound in `core::str::<impl str>::contains`
|
||||
|
|
Loading…
Add table
Reference in a new issue