// 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 #include "base/functional/callback.h" namespace base { void ComparingDifferentCallbackTypes() { // Comparing callbacks requires that they be the same type. RepeatingCallback c1; RepeatingCallback c2; c1 == c2; // expected-error {{invalid operands to binary expression ('RepeatingCallback' and 'RepeatingCallback')}} } 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 cb_derived; RepeatingCallback cb_base = cb_derived; // expected-error {{no viable conversion from 'RepeatingCallback' to 'RepeatingCallback'}} 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 returns_ptr_int_once; OnceCallback takes_ptr_float_once; RepeatingCallback returns_ptr_int_repeating; // Using distinct return types causes distinct `RepeatingCallback` template // instantiations, so we get assertion failures below where we expect. RepeatingCallback takes_ptr_float_repeating1; RepeatingCallback 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 returns_void_once; OnceCallback takes_float_once; RepeatingCallback returns_void_repeating; RepeatingCallback takes_float_repeating1; RepeatingCallback 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 returns_int_once; OnceCallback takes_void_once; RepeatingCallback returns_int_repeating; RepeatingCallback takes_void_repeating1; RepeatingCallback 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