Home | History | Annotate | Download | only in impl
      1 /*
      2  * Copyright 2014 Google Inc. All rights reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef FRUIT_INJECTION_ERRORS_H
     18 #define FRUIT_INJECTION_ERRORS_H
     19 
     20 #include <fruit/impl/fruit_assert.h>
     21 #include <fruit/impl/meta/set.h>
     22 
     23 namespace fruit {
     24 namespace impl {
     25 
     26 template <typename... Ts>
     27 struct AlwaysFalse {
     28   static constexpr bool value = false;
     29 };
     30 
     31 template <typename T>
     32 struct NoBindingFoundError {
     33   static_assert(AlwaysFalse<T>::value, "No explicit binding nor C::Inject definition was found for T.");
     34 };
     35 
     36 template <typename T, typename C>
     37 struct NoBindingFoundForAbstractClassError {
     38   static_assert(AlwaysFalse<T>::value,
     39                 "No explicit binding was found for T, and note that C is an abstract class (so Fruit can't auto-inject "
     40                 "this type, "
     41                 "even if it has an Inject typedef or an INJECT annotation that will be ignored).");
     42 };
     43 
     44 template <typename... Ts>
     45 struct RepeatedTypesError {
     46   static_assert(AlwaysFalse<Ts...>::value,
     47                 "A type was specified more than once. Requirements and provided types should be unique.");
     48 };
     49 
     50 template <typename... TypesInLoop>
     51 struct SelfLoopError {
     52   static_assert(AlwaysFalse<TypesInLoop...>::value,
     53                 "Found a loop in the dependencies! The types in TypesInLoop all depend on the next, and the "
     54                 "last one depends on the first.");
     55 };
     56 
     57 template <typename T, typename C>
     58 struct NonClassTypeError {
     59   static_assert(AlwaysFalse<T>::value, "A non-class type T was specified. Use C instead.");
     60 };
     61 
     62 template <typename AnnotatedT, typename T>
     63 struct AnnotatedTypeError {
     64   static_assert(AlwaysFalse<T>::value, "An annotated type was specified where a non-annotated type was expected.");
     65 };
     66 
     67 template <typename C>
     68 struct TypeAlreadyBoundError {
     69   static_assert(AlwaysFalse<C>::value, "Trying to bind C but it is already bound.");
     70 };
     71 
     72 template <typename RequiredSignature, typename SignatureInInjectTypedef>
     73 struct RequiredFactoryWithDifferentSignatureError {
     74   static_assert(AlwaysFalse<RequiredSignature>::value,
     75                 "The required C factory doesn't have the same signature as the Inject annotation in C.");
     76 };
     77 
     78 template <typename Signature, typename SignatureInLambda>
     79 struct AnnotatedSignatureDifferentFromLambdaSignatureError {
     80   static_assert(AlwaysFalse<Signature>::value,
     81                 "The annotated signature specified is not the same as the lambda's signature (after removing "
     82                 "annotations).");
     83 };
     84 
     85 template <typename... DuplicatedTypes>
     86 struct DuplicateTypesInComponentError {
     87   static_assert(AlwaysFalse<DuplicatedTypes...>::value,
     88                 "The installed component provides some types that are already provided by the current "
     89                 "component.");
     90 };
     91 
     92 template <typename... Requirements>
     93 struct InjectorWithRequirementsError {
     94   static_assert(AlwaysFalse<Requirements...>::value,
     95                 "Injectors can't have requirements. If you want Fruit to try auto-resolving the requirements "
     96                 "in the injector's scope, cast the component to a component with no requirements before "
     97                 "constructing the injector with it.");
     98 };
     99 
    100 template <typename C, typename CandidateSignature>
    101 struct InjectTypedefNotASignatureError {
    102   static_assert(AlwaysFalse<C>::value, "C::Inject should be a typedef to a signature, e.g. C(int)");
    103 };
    104 
    105 template <typename C, typename SignatureReturnType>
    106 struct InjectTypedefForWrongClassError {
    107   static_assert(AlwaysFalse<C>::value,
    108                 "C::Inject is a signature, but does not return a C. Maybe the class C has no Inject typedef "
    109                 "and inherited the base class' one? If that's not the case, make sure it returns just C, not "
    110                 "C* or other types.");
    111 };
    112 
    113 template <typename C>
    114 struct InjectTypedefWithAnnotationError {
    115   static_assert(AlwaysFalse<C>::value,
    116                 "C::Inject is a signature that returns an annotated type. The annotation must be removed, "
    117                 "Fruit will deduce the correct annotation based on how the required binding.");
    118 };
    119 
    120 template <typename CandidateSignature>
    121 struct NotASignatureError {
    122   static_assert(AlwaysFalse<CandidateSignature>::value,
    123                 "CandidateSignature was specified as parameter, but it's not a signature. Signatures are of "
    124                 "the form MyClass(int, float).");
    125 };
    126 
    127 template <typename CandidateLambda>
    128 struct NotALambdaError {
    129   static_assert(AlwaysFalse<CandidateLambda>::value,
    130                 "CandidateLambda was specified as parameter, but it's not a lambda.");
    131 };
    132 
    133 template <typename Signature>
    134 struct ConstructorDoesNotExistError {
    135   static_assert(AlwaysFalse<Signature>::value, "The specified constructor does not exist.");
    136 };
    137 
    138 template <typename I, typename C>
    139 struct NotABaseClassOfError {
    140   static_assert(AlwaysFalse<I>::value, "I is not a base class of C.");
    141 };
    142 
    143 template <typename ProviderType>
    144 struct FunctorUsedAsProviderError {
    145   static_assert(AlwaysFalse<ProviderType>::value,
    146                 "A stateful lambda or a non-lambda functor was used as provider. Only functions and stateless "
    147                 "lambdas can be used as providers.");
    148 };
    149 
    150 template <typename... ComponentRequirements>
    151 struct ComponentWithRequirementsInInjectorError {
    152   static_assert(AlwaysFalse<ComponentRequirements...>::value,
    153                 "When using the two-argument constructor of Injector, the component used as second parameter "
    154                 "must not have requirements (while the normalized component can), but the specified component "
    155                 "requires ComponentRequirements.");
    156 };
    157 
    158 template <typename... UnsatisfiedRequirements>
    159 struct UnsatisfiedRequirementsInNormalizedComponentError {
    160   static_assert(AlwaysFalse<UnsatisfiedRequirements...>::value,
    161                 "The requirements in UnsatisfiedRequirements are required by the NormalizedComponent but are "
    162                 "not provided by the Component (second parameter of the Injector constructor).");
    163 };
    164 
    165 template <typename... TypesNotProvided>
    166 struct TypesInInjectorNotProvidedError {
    167   static_assert(AlwaysFalse<TypesNotProvided...>::value,
    168                 "The types in TypesNotProvided are declared as provided by the injector, but none of the two "
    169                 "components passed to the Injector constructor provides them.");
    170 };
    171 
    172 template <typename... TypesProvidedAsConstOnly>
    173 struct TypesInInjectorProvidedAsConstOnlyError {
    174   static_assert(
    175       AlwaysFalse<TypesProvidedAsConstOnly...>::value,
    176       "The types in TypesProvidedAsConstOnly are declared as non-const provided types by the injector, but the "
    177       "components passed to the Injector constructor provide them as const only. You should mark them as const in the "
    178       "injector (e.g., switching from Injector<T> to Injector<const T>) or mark them as non-const in the "
    179       "Component/NormalizedComponent (e.g. switching from [Normalized]Component<const T> to "
    180       "[Normalized]Component<T>).");
    181 };
    182 
    183 template <typename T>
    184 struct TypeNotProvidedError {
    185   static_assert(AlwaysFalse<T>::value,
    186                 "Trying to get an instance of T, but it is not provided by this Provider/Injector.");
    187 };
    188 
    189 template <typename T>
    190 struct TypeProvidedAsConstOnlyError {
    191   static_assert(
    192       AlwaysFalse<T>::value,
    193       "Trying to get an instance of T, but it is only provided as a constant by this Provider/Injector and a non-const "
    194       "pointer/reference/Provider was requested. You should either switch to injecting a const value (e.g. switching "
    195       "from"
    196       " injecting T*, T&, std::unique_ptr<T> or Provider<T> to injecting a T, const T*, const T& or Provider<const T>) "
    197       "or get the value from an Injector/Provider that provides it as a non-const type (e.g. switching from calling "
    198       "get "
    199       "on an Injector<const T> or on a Provider<const T> to calling get on an Injector<T> or a Provider<T>).");
    200 };
    201 
    202 template <typename T>
    203 struct NonConstBindingRequiredButConstBindingProvidedError {
    204   static_assert(
    205       AlwaysFalse<T>::value,
    206       "The type T was provided as constant, however one of the constructors/providers/factories in this component "
    207       "requires it as a non-constant (or this Component declares it as a non-const provided/required type). "
    208       "If you want to only have a const binding for this type, you should change the places that use the type to "
    209       "inject "
    210       "a constant value (e.g. T, const T*, const T& and Provider<const T> are ok while you should avoid injecting T*, "
    211       "T&,"
    212       " std::unique_ptr<T> and Provider<T>) and if the type is in Component<...> make sure that it's marked as const "
    213       "there"
    214       " (e.g. Component<const T> and Component<Required<const T>> are ok while Component<T> and Component<Required<T>> "
    215       "are "
    216       "not. "
    217       "On the other hand, if you want to have a non-const binding for this type, you should switch to a non-const "
    218       "bindInstance (if you're binding an instance) or changing any installed component functions to declare the type "
    219       "as "
    220       "non-const, e.g. Component<T> or Component<Required<T>> instead of Component<const T> and "
    221       "Component<Required<const T>>.");
    222 };
    223 
    224 template <typename C, typename InjectSignature>
    225 struct NoConstructorMatchingInjectSignatureError {
    226   static_assert(AlwaysFalse<C>::value,
    227                 "C contains an Inject typedef but it's not constructible with the specified types");
    228 };
    229 
    230 template <typename ExpectedSignature, typename FunctorSignature>
    231 struct FunctorSignatureDoesNotMatchError {
    232   static_assert(AlwaysFalse<ExpectedSignature>::value,
    233                 "Unexpected functor signature (it should be the same as ExpectedSignature minus any Assisted "
    234                 "types).");
    235 };
    236 
    237 template <typename Signature>
    238 struct FactoryReturningPointerError {
    239   static_assert(AlwaysFalse<Signature>::value,
    240                 "The specified factory returns a pointer. This is not supported; return a value or an "
    241                 "std::unique_ptr instead.");
    242 };
    243 
    244 template <typename Lambda>
    245 struct LambdaWithCapturesError {
    246   // It's not guaranteed by the standard, but it's reasonable to expect lambdas with no captures
    247   // to be empty. This is always the case in GCC and Clang, but is not guaranteed to work in all
    248   // conforming C++ compilers. If this error happens for a lambda with no captures, please file a
    249   // bug at https://github.com/google/fruit/issues and indicate the compiler (with version) that
    250   // you're using.
    251   static_assert(AlwaysFalse<Lambda>::value, "Only lambdas with no captures are supported.");
    252 };
    253 
    254 template <typename Lambda>
    255 struct NonTriviallyCopyableLambdaError {
    256   // It's not guaranteed by the standard, but it's reasonable to expect lambdas with no captures
    257   // to be trivially copyable. This is always the case in GCC and Clang, but is not guaranteed to
    258   // work in all conforming C++ compilers. If this error happens for a lambda with no captures,
    259   // please file a bug at https://github.com/google/fruit/issues and indicate the compiler (with
    260   // version) that you're using.
    261   static_assert(AlwaysFalse<Lambda>::value,
    262                 "Only trivially copyable lambdas are supported. Make sure that your lambda has no captures.");
    263 };
    264 
    265 template <typename C>
    266 struct CannotConstructAbstractClassError {
    267   static_assert(AlwaysFalse<C>::value, "The specified class can't be constructed because it's an abstract class.");
    268 };
    269 
    270 template <typename C>
    271 struct InterfaceBindingToSelfError {
    272   static_assert(AlwaysFalse<C>::value,
    273                 "The type C was bound to itself. If this was intentional, to \"tell Fruit to inject the type"
    274                 " C\", this binding is unnecessary, just remove it. bind<I,C>() is to tell Fruit about"
    275                 " base-derived class relationships.");
    276 };
    277 
    278 template <typename TypeParameter, typename TypeOfValue>
    279 struct TypeMismatchInBindInstanceError {
    280   static_assert(AlwaysFalse<TypeParameter>::value,
    281                 "A type parameter was specified in bindInstance() but it doesn't match the value type"
    282                 " (even after removing the fruit::Annotation<>, if any). Please change the type parameter"
    283                 " to be the same as the type of the value (or a subclass).");
    284 };
    285 
    286 template <typename RequiredType>
    287 struct RequiredTypesInComponentArgumentsError {
    288   static_assert(AlwaysFalse<RequiredType>::value,
    289                 "A Required<...> type was passed as a non-first template parameter to fruit::Component or "
    290                 "fruit::NormalizedComponent. "
    291                 "All required types (if any) should be passed together as a single Required<> type passed as the first "
    292                 "type argument of fruit::Component (and fruit::NormalizedComponent). For example, write "
    293                 "fruit::Component<fruit::Required<Foo, Bar>, Baz> instead of "
    294                 "fruit::Component<fruit::Required<Foo>, fruit::Required<Bar>, Baz>.");
    295 };
    296 
    297 template <typename T>
    298 struct NonInjectableTypeError {
    299   static_assert(
    300       AlwaysFalse<T>::value,
    301       "The type T is not injectable. Injectable types are of the form X, X*, X&, const X, const X*, const X&, "
    302       "std::shared_ptr<X>, or Provider<X> where X is a fundamental type (excluding void), a class, a struct or "
    303       "an enum.");
    304 };
    305 
    306 template <typename T>
    307 struct ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError {
    308   static_assert(
    309       AlwaysFalse<T>::value,
    310       "The type T was declared as a const Required type in the returned Component, however a non-const binding is "
    311       "required. You should either change all the usages of this type so that they no longer require a non-const "
    312       "binding "
    313       "(i.e., you shouldn't inject T*, T& or std::shared_ptr<T>) or you should remove the 'const' in the type of the "
    314       "returned Component, e.g. changing fruit::Component<fruit::Required<const T, ...>, ...> to "
    315       "fruit::Component<fruit::Required<T, ...>, ...>.");
    316 };
    317 
    318 template <typename T>
    319 struct ProviderReturningPointerToAbstractClassWithNoVirtualDestructorError {
    320   static_assert(
    321       AlwaysFalse<T>::value,
    322       "registerProvider() was called with a lambda that returns a pointer to T, but T is an abstract class with no "
    323       "virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor (the one "
    324       "of "
    325       "the concrete class that was then casted to T). You must either add a virtual destructor to T or change the "
    326       "registerProvider() call to return a pointer to the concrete class (and then add a bind<T, TImpl>() so that T is "
    327       "bound).");
    328 };
    329 
    330 template <typename T>
    331 struct MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorError {
    332   static_assert(
    333       AlwaysFalse<T>::value,
    334       "registerMultibindingProvider() was called with a lambda that returns a pointer to T, but T is an abstract class "
    335       "with no virtual destructor so when the injector is deleted Fruit will be unable to call the right destructor "
    336       "(the "
    337       "one of the concrete class that was then casted to T). You must add a virtual destructor to T or replace the "
    338       "registerMultibindingProvider() with a registerProvider() for the concrete class and an addMultibinding() for T. "
    339       "Note that with the latter, if you end up with multiple addMultibinding() calls for the same concrete class, "
    340       "there will be only one instance of the concrete class in the injector, not one per addMultibdinding() call; if "
    341       "you want separate instances you might want to use annotated injection for the concrete class (so that there's "
    342       "one "
    343       "instance per annotation).");
    344 };
    345 
    346 template <typename T>
    347 struct RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorError {
    348   static_assert(AlwaysFalse<T>::value,
    349                 "registerFactory() was called with a lambda that returns a std::unique_ptr<T>, but T is an abstract "
    350                 "class with no "
    351                 "virtual destructor so when the returned std::unique_ptr<T> object is deleted the wrong destructor "
    352                 "will be called "
    353                 "(T's destructor instead of the one of the concrete class that was then casted to T). You must add a "
    354                 "virtual destructor to T.");
    355 };
    356 
    357 template <typename BaseFactory, typename DerivedFactory>
    358 struct FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError {
    359   static_assert(
    360       AlwaysFalse<BaseFactory>::value,
    361       "Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr "
    362       "of "
    363       "a class with no virtual destructor, so when the std::unique_ptr object is destroyed the wrong destructor would "
    364       "be "
    365       "called (the one in the base class instead of the derived class). To avoid this, you must add a virtual "
    366       "destructor to the base class.");
    367 };
    368 
    369 template <typename Arg>
    370 struct IncorrectArgTypePassedToInstallComponentFuntionsError {
    371     static_assert(
    372         AlwaysFalse<Arg>::value,
    373         "All arguments passed to installComponentFunctions() must be fruit::ComponentFunction<...> objects but an "
    374         "argument with type Arg was passed instead.");
    375 };
    376 
    377 struct LambdaWithCapturesErrorTag {
    378   template <typename Lambda>
    379   using apply = LambdaWithCapturesError<Lambda>;
    380 };
    381 
    382 struct NonTriviallyCopyableLambdaErrorTag {
    383   template <typename Lambda>
    384   using apply = NonTriviallyCopyableLambdaError<Lambda>;
    385 };
    386 
    387 struct FactoryReturningPointerErrorTag {
    388   template <typename Signature>
    389   using apply = FactoryReturningPointerError<Signature>;
    390 };
    391 
    392 struct NoBindingFoundErrorTag {
    393   template <typename T>
    394   using apply = NoBindingFoundError<T>;
    395 };
    396 
    397 struct RepeatedTypesErrorTag {
    398   template <typename... Ts>
    399   using apply = RepeatedTypesError<Ts...>;
    400 };
    401 
    402 struct SelfLoopErrorTag {
    403   template <typename... TypesInLoop>
    404   using apply = SelfLoopError<TypesInLoop...>;
    405 };
    406 
    407 struct NonClassTypeErrorTag {
    408   template <typename T, typename C>
    409   using apply = NonClassTypeError<T, C>;
    410 };
    411 
    412 struct AnnotatedTypeErrorTag {
    413   template <typename T, typename C>
    414   using apply = AnnotatedTypeError<T, C>;
    415 };
    416 
    417 struct TypeAlreadyBoundErrorTag {
    418   template <typename C>
    419   using apply = TypeAlreadyBoundError<C>;
    420 };
    421 
    422 struct RequiredFactoryWithDifferentSignatureErrorTag {
    423   template <typename RequiredSignature, typename SignatureInInjectTypedef>
    424   using apply = RequiredFactoryWithDifferentSignatureError<RequiredSignature, SignatureInInjectTypedef>;
    425 };
    426 
    427 struct AnnotatedSignatureDifferentFromLambdaSignatureErrorTag {
    428   template <typename Signature, typename SignatureInLambda>
    429   using apply = AnnotatedSignatureDifferentFromLambdaSignatureError<Signature, SignatureInLambda>;
    430 };
    431 
    432 struct DuplicateTypesInComponentErrorTag {
    433   template <typename... DuplicatedTypes>
    434   using apply = DuplicateTypesInComponentError<DuplicatedTypes...>;
    435 };
    436 
    437 struct InjectorWithRequirementsErrorTag {
    438   template <typename... Requirements>
    439   using apply = InjectorWithRequirementsError<Requirements...>;
    440 };
    441 
    442 struct ComponentWithRequirementsInInjectorErrorTag {
    443   template <typename... ComponentRequirements>
    444   using apply = ComponentWithRequirementsInInjectorError<ComponentRequirements...>;
    445 };
    446 
    447 struct InjectTypedefNotASignatureErrorTag {
    448   template <typename C, typename TypeInInjectTypedef>
    449   using apply = InjectTypedefNotASignatureError<C, TypeInInjectTypedef>;
    450 };
    451 
    452 struct InjectTypedefForWrongClassErrorTag {
    453   template <typename C, typename ReturnTypeOfInjectTypedef>
    454   using apply = InjectTypedefForWrongClassError<C, ReturnTypeOfInjectTypedef>;
    455 };
    456 
    457 struct InjectTypedefWithAnnotationErrorTag {
    458   template <typename C>
    459   using apply = InjectTypedefWithAnnotationError<C>;
    460 };
    461 
    462 struct UnsatisfiedRequirementsInNormalizedComponentErrorTag {
    463   template <typename... UnsatisfiedRequirements>
    464   using apply = UnsatisfiedRequirementsInNormalizedComponentError<UnsatisfiedRequirements...>;
    465 };
    466 
    467 struct TypesInInjectorNotProvidedErrorTag {
    468   template <typename... TypesNotProvided>
    469   using apply = TypesInInjectorNotProvidedError<TypesNotProvided...>;
    470 };
    471 
    472 struct TypesInInjectorProvidedAsConstOnlyErrorTag {
    473   template <typename... TypesProvidedAsConstOnly>
    474   using apply = TypesInInjectorProvidedAsConstOnlyError<TypesProvidedAsConstOnly...>;
    475 };
    476 
    477 struct FunctorUsedAsProviderErrorTag {
    478   template <typename ProviderType>
    479   using apply = FunctorUsedAsProviderError<ProviderType>;
    480 };
    481 
    482 struct ConstructorDoesNotExistErrorTag {
    483   template <typename Signature>
    484   using apply = ConstructorDoesNotExistError<Signature>;
    485 };
    486 
    487 struct NotABaseClassOfErrorTag {
    488   template <typename I, typename C>
    489   using apply = NotABaseClassOfError<I, C>;
    490 };
    491 
    492 struct NotASignatureErrorTag {
    493   template <typename CandidateSignature>
    494   using apply = NotASignatureError<CandidateSignature>;
    495 };
    496 
    497 struct NotALambdaErrorTag {
    498   template <typename CandidateLambda>
    499   using apply = NotALambdaError<CandidateLambda>;
    500 };
    501 
    502 struct TypeNotProvidedErrorTag {
    503   template <typename T>
    504   using apply = TypeNotProvidedError<T>;
    505 };
    506 
    507 struct TypeProvidedAsConstOnlyErrorTag {
    508   template <typename T>
    509   using apply = TypeProvidedAsConstOnlyError<T>;
    510 };
    511 
    512 struct NonConstBindingRequiredButConstBindingProvidedErrorTag {
    513   template <typename T>
    514   using apply = NonConstBindingRequiredButConstBindingProvidedError<T>;
    515 };
    516 
    517 struct NoConstructorMatchingInjectSignatureErrorTag {
    518   template <typename C, typename InjectSignature>
    519   using apply = NoConstructorMatchingInjectSignatureError<C, InjectSignature>;
    520 };
    521 
    522 struct FunctorSignatureDoesNotMatchErrorTag {
    523   template <typename ExpectedSignature, typename FunctorSignature>
    524   using apply = FunctorSignatureDoesNotMatchError<ExpectedSignature, FunctorSignature>;
    525 };
    526 
    527 struct CannotConstructAbstractClassErrorTag {
    528   template <typename C>
    529   using apply = CannotConstructAbstractClassError<C>;
    530 };
    531 
    532 struct NoBindingFoundForAbstractClassErrorTag {
    533   template <typename T, typename C>
    534   using apply = NoBindingFoundForAbstractClassError<T, C>;
    535 };
    536 
    537 struct InterfaceBindingToSelfErrorTag {
    538   template <typename C>
    539   using apply = InterfaceBindingToSelfError<C>;
    540 };
    541 
    542 struct TypeMismatchInBindInstanceErrorTag {
    543   template <typename TypeParameter, typename TypeOfValue>
    544   using apply = TypeMismatchInBindInstanceError<TypeParameter, TypeOfValue>;
    545 };
    546 
    547 struct RequiredTypesInComponentArgumentsErrorTag {
    548   template <typename RequiredType>
    549   using apply = RequiredTypesInComponentArgumentsError<RequiredType>;
    550 };
    551 
    552 struct NonInjectableTypeErrorTag {
    553   template <typename T>
    554   using apply = NonInjectableTypeError<T>;
    555 };
    556 
    557 struct ConstBindingDeclaredAsRequiredButNonConstBindingRequiredErrorTag {
    558   template <typename T>
    559   using apply = ConstBindingDeclaredAsRequiredButNonConstBindingRequiredError<T>;
    560 };
    561 
    562 struct ProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag {
    563   template <typename T>
    564   using apply = ProviderReturningPointerToAbstractClassWithNoVirtualDestructorError<T>;
    565 };
    566 
    567 struct MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorErrorTag {
    568   template <typename T>
    569   using apply = MultibindingProviderReturningPointerToAbstractClassWithNoVirtualDestructorError<T>;
    570 };
    571 
    572 struct RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorErrorTag {
    573   template <typename T>
    574   using apply = RegisterFactoryForUniquePtrOfAbstractClassWithNoVirtualDestructorError<T>;
    575 };
    576 
    577 struct FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorErrorTag {
    578   template <typename BaseFactory, typename DerivedFactory>
    579   using apply = FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError<BaseFactory, DerivedFactory>;
    580 };
    581 
    582 struct IncorrectArgTypePassedToInstallComponentFuntionsErrorTag {
    583   template <typename Arg>
    584   using apply = IncorrectArgTypePassedToInstallComponentFuntionsError<Arg>;
    585 };
    586 
    587 } // namespace impl
    588 } // namespace fruit
    589 
    590 #endif // FRUIT_INJECTION_ERRORS_H
    591