mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Add support for unsafe as operator to the toolchain. (#5993)
Following the direction of #5913, add support for parsing an `unsafe as` operator. For now, we allow one additional conversion using `unsafe as` beyond the conversions supported by `as`: we permit pointer conversions that remove qualifiers, such as `const T*` -> `T*`.
This commit is contained in:
@@ -278,12 +278,24 @@ auto HandleExprLoop(Context& context) -> void {
|
||||
auto operator_kind = context.PositionKind();
|
||||
auto trailing_operator = PrecedenceGroup::ForTrailing(
|
||||
operator_kind, context.IsTrailingOperatorInfix());
|
||||
|
||||
if (!trailing_operator) {
|
||||
if (state.has_error) {
|
||||
context.ReturnErrorOnState();
|
||||
// TODO: Generalize this to handle a sequence of operator modifiers once we
|
||||
// have more than one.
|
||||
if (context.PositionIs(Lex::TokenKind::Unsafe)) {
|
||||
operator_kind = context.PositionKind(Lookahead::NextToken);
|
||||
trailing_operator = PrecedenceGroup::ForTrailing(
|
||||
operator_kind, context.IsTrailingOperatorInfix());
|
||||
}
|
||||
|
||||
if (!trailing_operator) {
|
||||
if (state.has_error) {
|
||||
context.ReturnErrorOnState();
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto [operator_precedence, is_binary] = *trailing_operator;
|
||||
|
||||
// TODO: If this operator is ambiguous with either the ambient precedence
|
||||
@@ -323,6 +335,23 @@ auto HandleExprLoop(Context& context) -> void {
|
||||
: Context::OperatorFixity::Postfix);
|
||||
}
|
||||
|
||||
// For operator modifiers, wrap the first operand in the modifier.
|
||||
if (context.PositionIs(Lex::TokenKind::Unsafe)) {
|
||||
if (context.PositionIs(Lex::TokenKind::As, Lookahead::NextToken)) {
|
||||
context.AddNode<NodeKind::UnsafeModifier>(context.Consume(),
|
||||
state.has_error);
|
||||
} else {
|
||||
CARBON_DIAGNOSTIC(ModifierNotAllowedOnOperator, Error,
|
||||
"`{0}` not allowed on operator `{1}`", Lex::TokenKind,
|
||||
Lex::TokenKind);
|
||||
context.emitter().Emit(*context.position(), ModifierNotAllowedOnOperator,
|
||||
context.PositionKind(),
|
||||
context.PositionKind(Lookahead::NextToken));
|
||||
context.Consume();
|
||||
state.has_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
state.token = context.Consume();
|
||||
state.lhs_precedence = operator_precedence;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user