2797. Trait precondition violations

Section: 23.15.2 [meta.type.synop] Status: Open Submitter: Russia Opened: 2016-11-09 Last modified: 2017-06-16

Priority: 2

View other active issues in [meta.type.synop].

View all other issues in [meta.type.synop].

View all issues with Open status.

Discussion:

Addresses RU 2

Failed prerequirement for the type trait must result in ill-formed program. Otherwise hard detectable errors will happen:

#include <type_traits>

struct foo;

void damage_type_trait() {
  // must be ill-formed
  std::is_constructible<foo, foo>::value;
}

struct foo{};

int main() {
  static_assert(
    // produces invalid result
    std::is_constructible<foo, foo>::value,
    "foo must be constructible from foo"
  );
}

Suggested resolution:

Add to the end of the [meta.type.synop] section:

Program is ill-formed if precondition for the type trait is violated.

[2016-11-09, Jonathan provides wording]

[Issues Telecon 16-Dec-2016]

Priority 2

[2017-03-02, Daniel comments]

LWG 2939 has been created to signal that some of our current type trait constraints are not quite correct and I recommend not to enforce the required diagnostics for traits that are sensitive to mismatches of the current approximate rules.

[2017-03-03, Kona Friday morning]

Unanimous consent to adopt this for C++17, but due to a misunderstanding, it wasn't on the ballot

Setting status to 'Ready' so we'll get it in immediately post-C++17

[2017-06-15 request from Daniel]

I don't believe that this should be "Ready"; I added the extra note to LWG 2797 *and* added the new issue 2939 exactly to *prevent* 2797 being accepted for C++17

Setting status back to 'Open'

Proposed resolution:

This wording is relative to N4606.

  1. Add a new paragraph after 23.15.4.3 [meta.unary.prop] paragraph 3:

    -?- If an instantiation of any template declared in this subclause fails to meet the preconditions, the program is ill-formed.

  2. Change the specification for alignment_of in Table 39 in 23.15.5 [meta.unary.prop.query]:

    Table 39 — Type property queries
    template <class T> struct alignment_of; alignof(T).
    Requires: alignof(T) shall be a valid expression (5.3.6), otherwise the program is ill-formed
  3. Change the specification for is_base_of, is_convertible, is_callable, and is_nothrow_callable in Table 40 in 23.15.6 [meta.rel]:

    Table 40 — Type relationship predicates
    […]
    template <class Base, class
    Derived>
    struct is_base_of;
    […] If Base and Derived are
    non-union class types and are
    different types (ignoring possible
    cv-qualifiers) then Derived shall
    be a complete type, otherwise the program is ill-formed.
    [Note: Base classes that
    are private, protected, or ambiguous are,
    nonetheless, base classes. — end note]
    template <class From, class To>
    struct is_convertible;
    see below From and To shall be complete
    types, arrays of unknown bound,
    or (possibly cv-qualified) void
    types, otherwise the program is
    ill-formed
    .
    template <class Fn, class...
    ArgTypes, class R>
    struct is_callable<
    Fn(ArgTypes...), R>;
    […] Fn, R, and all types in the
    parameter pack ArgTypes shall
    be complete types, (possibly
    cv-qualified) void, or arrays of
    unknown bound,
    otherwise the program is ill-formed
    .
    template <class Fn, class...
    ArgTypes, class R>
    struct is_nothrow_callable<
    Fn(ArgTypes...), R>;
    […] Fn, R, and all types in the
    parameter pack ArgTypes shall
    be complete types, (possibly
    cv-qualified) void, or arrays of
    unknown bound,
    otherwise the program is ill-formed
    .
  4. Add a new paragraph after 23.15.7 [meta.trans] paragraph 2:

    -2- Each of the templates in this subclause shall be a TransformationTrait (20.15.1).

    -?- If an instantiation of any template declared in this subclause fails to meet the Requires: preconditions, the program is ill-formed.