1// Copyright 2011 The Chromium Authors 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// This is a "No Compile Test" suite. 6// http://dev.chromium.org/developers/testing/no-compile-tests 7 8#include <utility> 9 10#include "base/functional/callback.h" 11 12namespace base { 13 14void ComparingDifferentCallbackTypes() { 15 // Comparing callbacks requires that they be the same type. 16 RepeatingCallback<void()> c1; 17 RepeatingCallback<int()> c2; 18 c1 == c2; // expected-error {{invalid operands to binary expression ('RepeatingCallback<void ()>' and 'RepeatingCallback<int ()>')}} 19} 20 21void ConvertingSuperclassReturn() { 22 // A callback that returns a `Derived` should not be implicitly converted to a 23 // callback that returns a `Base`. This is technically safe, but it surprises 24 // users and generally means the author is doing something other than what 25 // they intended. 26 struct Base {}; 27 struct Derived : public Base {}; 28 RepeatingCallback<Derived()> cb_derived; 29 RepeatingCallback<Base()> cb_base = cb_derived; // expected-error {{no viable conversion from 'RepeatingCallback<Derived ()>' to 'RepeatingCallback<Base ()>'}} 30 cb_base = cb_derived; // expected-error {{no viable overloaded '='}} 31} 32 33void ChainingWithTypeMismatch() { 34 // Calling `.Then()` requires that the return type of the first callback be 35 // convertible to the arg type of the second callback. 36 37 // non-void -> incompatible non-void 38 OnceCallback<int*()> returns_ptr_int_once; 39 OnceCallback<void(float*)> takes_ptr_float_once; 40 RepeatingCallback<int*()> returns_ptr_int_repeating; 41 // Using distinct return types causes distinct `RepeatingCallback` template 42 // instantiations, so we get assertion failures below where we expect. 43 RepeatingCallback<void(float*)> takes_ptr_float_repeating1; 44 RepeatingCallback<int(float*)> takes_ptr_float_repeating2; 45 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|.}} 46 returns_ptr_int_repeating.Then(takes_ptr_float_repeating1); // expected-error@*:* {{|then| callback's parameter must be constructible from return type of |this|.}} 47 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|.}} 48 49 // void -> non-void 50 OnceCallback<void()> returns_void_once; 51 OnceCallback<void(float)> takes_float_once; 52 RepeatingCallback<void()> returns_void_repeating; 53 RepeatingCallback<void(float)> takes_float_repeating1; 54 RepeatingCallback<int(float)> takes_float_repeating2; 55 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.}} 56 returns_void_repeating.Then(takes_float_repeating1); // expected-error@*:* {{|then| callback cannot accept parameters if |this| has a void return type.}} 57 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.}} 58 59 // non-void -> void 60 OnceCallback<int()> returns_int_once; 61 OnceCallback<void()> takes_void_once; 62 RepeatingCallback<int()> returns_int_repeating; 63 RepeatingCallback<void()> takes_void_repeating1; 64 RepeatingCallback<int()> takes_void_repeating2; 65 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.}} 66 returns_int_repeating.Then(takes_void_repeating1); // expected-error@*:* {{|then| callback must accept exactly one parameter if |this| has a non-void return type.}} 67 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.}} 68} 69 70} // namespace base 71