Skip to content

Commit e78d538

Browse files
committed
transpile: Allow EnumConstant DeclRefs and casts to enums in patterns
1 parent 698955d commit e78d538

2 files changed

Lines changed: 47 additions & 5 deletions

File tree

c2rust-transpile/src/translator/enums.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use syn::Expr;
44

55
use crate::{
66
diagnostics::TranslationResult,
7-
translator::{signed_int_expr, ConvertedDecl, EnumMode, ExprContext, Translation},
7+
translator::{
8+
signed_int_expr, ConvertedDecl, EnumMode, ExprContext, Translation, TranslationError,
9+
},
810
with_stmts::WithStmts,
911
CDeclKind, CEnumConstantId, CEnumId, CQualTypeId, CTypeId, CTypeKind, ConstIntExpr,
1012
};
@@ -105,7 +107,15 @@ impl<'c> Translation<'c> {
105107
) -> TranslationResult<WithStmts<Box<Expr>>> {
106108
match self.tcfg.enum_mode {
107109
// First extract the enum's inner type...
108-
EnumMode::NewType => val = self.integer_from_enum(val),
110+
EnumMode::NewType => {
111+
if ctx.is_pattern {
112+
return Err(TranslationError::generic(
113+
"cast from enum is not supported in patterns",
114+
));
115+
}
116+
117+
val = self.integer_from_enum(val);
118+
}
109119
EnumMode::Consts => {}
110120
}
111121

@@ -149,7 +159,15 @@ impl<'c> Translation<'c> {
149159

150160
match self.tcfg.enum_mode {
151161
// Enum-to-enum casts need to be translated via the inner value as an intermediate.
152-
EnumMode::NewType => val = self.integer_from_enum(val),
162+
EnumMode::NewType => {
163+
if ctx.is_pattern {
164+
return Err(TranslationError::generic(
165+
"cast from enum is not supported in patterns",
166+
));
167+
}
168+
169+
val = self.integer_from_enum(val);
170+
}
153171
EnumMode::Consts => {}
154172
}
155173

@@ -167,6 +185,12 @@ impl<'c> Translation<'c> {
167185
}
168186

169187
EnumMode::Consts => {
188+
if ctx.is_pattern {
189+
return Err(TranslationError::generic(
190+
"cast to enum is not supported in patterns",
191+
));
192+
}
193+
170194
let source_type_kind = &self.ast_context.resolve_type(source_cty.ctype).kind;
171195
let enum_integral_type_kind =
172196
&self.ast_context.resolve_type(enum_integral_type.ctype).kind;

c2rust-transpile/src/translator/mod.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ pub struct Translation<'c> {
294294
extern_crates: RefCell<CrateSet>,
295295

296296
// Translation state and utilities
297-
type_converter: RefCell<TypeConverter>,
297+
pub type_converter: RefCell<TypeConverter>,
298298
renamer: RefCell<Renamer<CDeclId>>,
299299
zero_inits: RefCell<ZeroInits>,
300300
function_context: RefCell<FuncContext>,
@@ -2969,6 +2969,7 @@ impl<'c> Translation<'c> {
29692969
expr_kind,
29702970
CExprKind::Paren(..)
29712971
| CExprKind::ConstantExpr(..)
2972+
| CExprKind::DeclRef(..)
29722973
| CExprKind::Literal(..)
29732974
| CExprKind::ImplicitCast(..)
29742975
| CExprKind::ExplicitCast(..)
@@ -3395,6 +3396,12 @@ impl<'c> Translation<'c> {
33953396
);
33963397
}
33973398

3399+
if ctx.is_pattern {
3400+
return Err(TranslationError::generic(
3401+
"non-EnumConstant DeclRefs are not supported in patterns",
3402+
));
3403+
}
3404+
33983405
let varname = decl.get_name().expect("expected variable name").to_owned();
33993406
let rustname = self
34003407
.renamer
@@ -3707,7 +3714,12 @@ impl<'c> Translation<'c> {
37073714
return Ok(val);
37083715
}
37093716

3710-
if ctx.is_pattern && !matches!(kind, CastKind::ToVoid | CastKind::ConstCast) {
3717+
if ctx.is_pattern
3718+
&& !matches!(
3719+
kind,
3720+
CastKind::ToVoid | CastKind::ConstCast | CastKind::IntegralCast
3721+
)
3722+
{
37113723
return Err(TranslationError::generic(
37123724
"cast kind is not supported in patterns",
37133725
));
@@ -3733,6 +3745,12 @@ impl<'c> Translation<'c> {
37333745
| CastKind::BooleanToSignedIntegral => {
37343746
let target_ty = self.convert_type(target_cty.ctype)?;
37353747

3748+
if ctx.is_pattern && !target_ty_kind.is_enum() {
3749+
return Err(TranslationError::generic(
3750+
"integral casts to non-enums are not supported in patterns",
3751+
));
3752+
}
3753+
37363754
if let CTypeKind::LongDouble | CTypeKind::Float128 = target_ty_kind {
37373755
if let CTypeKind::LongDouble | CTypeKind::Float128 =
37383756
self.ast_context[source_cty.ctype].kind

0 commit comments

Comments
 (0)