| // Copyright 2011 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // This is a "No Compile Test" suite. |
| // http://dev.chromium.org/developers/testing/no-compile-tests |
| |
| #include <utility> |
| |
| #include "base/functional/callback.h" |
| |
| namespace base { |
| |
| void ComparingDifferentCallbackTypes() { |
| // Comparing callbacks requires that they be the same type. |
| RepeatingCallback<void()> c1; |
| RepeatingCallback<int()> c2; |
| c1 == c2; // expected-error {{invalid operands to binary expression ('RepeatingCallback<void ()>' and 'RepeatingCallback<int ()>')}} |
| } |
| |
| void ConvertingSuperclassReturn() { |
| // A callback that returns a `Derived` should not be implicitly converted to a |
| // callback that returns a `Base`. This is technically safe, but it surprises |
| // users and generally means the author is doing something other than what |
| // they intended. |
| struct Base {}; |
| struct Derived : public Base {}; |
| RepeatingCallback<Derived()> cb_derived; |
| RepeatingCallback<Base()> cb_base = cb_derived; // expected-error {{no viable conversion from 'RepeatingCallback<Derived ()>' to 'RepeatingCallback<Base ()>'}} |
| cb_base = cb_derived; // expected-error {{no viable overloaded '='}} |
| } |
| |
| void ChainingWithTypeMismatch() { |
| // Calling `.Then()` requires that the return type of the first callback be |
| // convertible to the arg type of the second callback. |
| |
| // non-void -> incompatible non-void |
| OnceCallback<int*()> returns_ptr_int_once; |
| OnceCallback<void(float*)> takes_ptr_float_once; |
| RepeatingCallback<int*()> returns_ptr_int_repeating; |
| // Using distinct return types causes distinct `RepeatingCallback` template |
| // instantiations, so we get assertion failures below where we expect. |
| RepeatingCallback<void(float*)> takes_ptr_float_repeating1; |
| RepeatingCallback<int(float*)> takes_ptr_float_repeating2; |
| std::move(returns_ptr_int_once).Then(std::move(takes_ptr_float_once)); // expected-error@*:* {{|then| callback's parameter must be constructible from return type of |this|.}} |
| returns_ptr_int_repeating.Then(takes_ptr_float_repeating1); // expected-error@*:* {{|then| callback's parameter must be constructible from return type of |this|.}} |
| std::move(returns_ptr_int_repeating).Then(std::move(takes_ptr_float_repeating2)); // expected-error@*:* {{|then| callback's parameter must be constructible from return type of |this|.}} |
| |
| // void -> non-void |
| OnceCallback<void()> returns_void_once; |
| OnceCallback<void(float)> takes_float_once; |
| RepeatingCallback<void()> returns_void_repeating; |
| RepeatingCallback<void(float)> takes_float_repeating1; |
| RepeatingCallback<int(float)> takes_float_repeating2; |
| std::move(returns_void_once).Then(std::move(takes_float_once)); // expected-error@*:* {{|then| callback cannot accept parameters if |this| has a void return type.}} |
| returns_void_repeating.Then(takes_float_repeating1); // expected-error@*:* {{|then| callback cannot accept parameters if |this| has a void return type.}} |
| std::move(returns_void_repeating).Then(std::move(takes_float_repeating2)); // expected-error@*:* {{|then| callback cannot accept parameters if |this| has a void return type.}} |
| |
| // non-void -> void |
| OnceCallback<int()> returns_int_once; |
| OnceCallback<void()> takes_void_once; |
| RepeatingCallback<int()> returns_int_repeating; |
| RepeatingCallback<void()> takes_void_repeating1; |
| RepeatingCallback<int()> takes_void_repeating2; |
| std::move(returns_int_once).Then(std::move(takes_void_once)); // expected-error@*:* {{|then| callback must accept exactly one parameter if |this| has a non-void return type.}} |
| returns_int_repeating.Then(takes_void_repeating1); // expected-error@*:* {{|then| callback must accept exactly one parameter if |this| has a non-void return type.}} |
| std::move(returns_int_repeating).Then(std::move(takes_void_repeating2)); // expected-error@*:* {{|then| callback must accept exactly one parameter if |this| has a non-void return type.}} |
| } |
| |
| } // namespace base |