Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[expr.await] lacks the specification for overload "operator co_await" #5208

Open
xmh0511 opened this issue Jan 15, 2022 · 0 comments
Open

[expr.await] lacks the specification for overload "operator co_await" #5208

xmh0511 opened this issue Jan 15, 2022 · 0 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Jan 15, 2022

[over.oper.general] says

The co_­await operator is described completely in [expr.await]. The attributes and restrictions found in the rest of [over.oper] do not apply to it unless explicitly stated in [expr.await].

we only mention operator co_await operator in [expr.await] p3

Evaluation of an await-expression involves the following auxiliary types, expressions, and objects:

  • [...]
  • o is determined by enumerating the applicable operator co_­await functions for an argument a ([over.match.oper]), and choosing the best one through overload resolution ([over.match]). If overload resolution is ambiguous, the program is ill-formed. If no viable functions are found, o is a. Otherwise, o is a call to the selected function with the argument a. If o would be a prvalue, the temporary materialization conversion ([conv.rval]) is applied.

Except that, we didn't mention operator co_await in [expr.await] any more. In the complete subclause [expr.await], we never give the specification that which scopes an operator co_await can be declared in, what number of parameters the function shall have, and how the lookup rules perform to find the function. We never state these details in [expr.await].

struct Awaiter{
    bool await_ready(){return false;}
    void await_suspend(std::coroutine_handle<>){}
    void await_resume(){}
};
struct CoroutineType{
    struct promise_type;
    using handle = std::coroutine_handle<promise_type>;
    struct promise_type{
        auto initial_suspend(){
            return std::suspend_always{};
        }
        auto final_suspend() noexcept{
            return std::suspend_always{};
        }
        auto get_return_object(){
            return CoroutineType{handle::from_promise(*this)};
        }
        void unhandled_exception(){

        }
    };
    handle coro;
};

// contrast 1
struct C{
    Awaiter operator co_await(){return Awaiter{};}
};
CoroutineType fun(){
    co_await C{};
} 

// contrast 2
struct D{};
Awaiter operator co_await(D){
   return Awaiter{};
}

CoroutineType  fun2(){
   co_await  D{};
}

// contrast 3
namespace X{
    struct ADL{};
    Awaiter operator co_await(ADL){
        return Awaiter{};
    }
}
CoroutineType fun3(){
    co_await X::ADL{};
}

By testing the implementations(e.g., Clang and GCC), it seems that having a different scope in which operator co_await is declared, the function should accompany by a different number of parameters. As well, a different lookup rule will perform to find the declarations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant