diff --git a/c2rust-ast-builder/src/builder.rs b/c2rust-ast-builder/src/builder.rs index 07518e0f33..69aa730727 100644 --- a/c2rust-ast-builder/src/builder.rs +++ b/c2rust-ast-builder/src/builder.rs @@ -1228,6 +1228,20 @@ impl Builder { }) } + pub fn tuple_struct_pat(self, path: Pa, qself: Option, elems: Vec) -> Pat + where + Pa: Make, + { + let path = path.make(&self); + Pat::TupleStruct(PatTupleStruct { + attrs: self.attrs, + qself, + path, + paren_token: token::Paren(self.span), + elems: punct(elems), + }) + } + // Types pub fn barefn_ty(self, decl: BareFnTyParts) -> Box { diff --git a/c2rust-refactor/src/macros.rs b/c2rust-refactor/src/macros.rs index a286197d36..689db7a60e 100644 --- a/c2rust-refactor/src/macros.rs +++ b/c2rust-refactor/src/macros.rs @@ -13,7 +13,14 @@ macro_rules! match_or_else { ([$e:expr] $($arm_pat:pat => $arm_body:expr),*; $or_else:expr) => { match $e { $( $arm_pat => $arm_body, )* - ref x @ _ => $or_else(x), + _ => $or_else, + } + }; + + ([$e:expr] $($arm_pat:pat => $arm_body:expr),*; $or_else_var:ident => $or_else:expr) => { + match $e { + $( $arm_pat => $arm_body, )* + ref $or_else_var @ _ => $or_else, } }; } @@ -22,11 +29,11 @@ macro_rules! match_or_else { macro_rules! expect { ([$e:expr] $arm_pat:pat => $arm_body:expr) => { $crate::match_or_else!([$e] $arm_pat => $arm_body; - |x| panic!("expected {}, got {:?}", stringify!($arm_pat), x)) + x => panic!("expected {}, got {:?}", stringify!($arm_pat), x)) }; ([$e:expr] $($arm_pat:pat => $arm_body:expr),*) => { $crate::match_or_else!([$e] $($arm_pat => $arm_body),*; - |x| panic!("expected one of: {}, got {:?}", stringify!($($arm_pat),*), x)) + x => panic!("expected one of: {}, got {:?}", stringify!($($arm_pat),*), x)) }; } @@ -35,6 +42,28 @@ macro_rules! unpack { ([$e:expr] $enum_:ident :: $variant:ident ( $($arg:ident),* )) => { let ($($arg,)*) = $crate::expect!([$e] $enum_::$variant($($arg),*) => ($($arg,)*)); }; + + ( + [$e:expr] + $enum_:ident :: $variant:ident ( $($arg:ident),* ); + $or_else:expr + ) => { + let ($($arg,)*) = $crate::match_or_else!( + [$e] $enum_::$variant($($arg),*) => ($($arg,)*); + $or_else + ); + }; + + ( + [$e:expr] + $enum_:ident :: $variant:ident ( $($arg:ident),* ); + $or_else_var:ident => $or_else:expr + ) => { + let ($($arg,)*) = $crate::match_or_else!( + [$e] $enum_::$variant($($arg),*) => ($($arg,)*); + $or_else_var => $or_else + ); + }; } #[macro_export] diff --git a/c2rust-refactor/src/path_edit.rs b/c2rust-refactor/src/path_edit.rs index b503055288..0e7e15edd7 100644 --- a/c2rust-refactor/src/path_edit.rs +++ b/c2rust-refactor/src/path_edit.rs @@ -124,7 +124,11 @@ where _ => {} } - unpack!([&mut t.kind] TyKind::Path(qself, path)); + if !matches!(t.kind, TyKind::Path(..)) { + panic!("{qpath:?}"); + } + + unpack!([&mut t.kind] TyKind::Path(qself, path); return); let (new_qself, new_path) = self.handle_qpath(id, qself.clone(), path.clone(), qpath); *qself = new_qself; diff --git a/c2rust-transpile/src/c_ast/mod.rs b/c2rust-transpile/src/c_ast/mod.rs index e6b7516991..2996b394d0 100644 --- a/c2rust-transpile/src/c_ast/mod.rs +++ b/c2rust-transpile/src/c_ast/mod.rs @@ -780,6 +780,14 @@ impl TypedAstContext { TypeOf(ty) => ty, Paren(ty) => ty, Auto(ty) => ty, + + // As an exception, resolve typedefs in `prenamed_decls`, because they do not + // get translated as type aliases in the final code. + Typedef(decl) if self.prenamed_decls.contains_key(&decl) => match self[decl].kind { + CDeclKind::Typedef { typ: ty, .. } => ty.ctype, + _ => panic!("Typedef decl did not point to a typedef"), + }, + _ => return typ, }; self.resolve_type_id_no_typedef(ty) diff --git a/c2rust-transpile/src/cfg/mod.rs b/c2rust-transpile/src/cfg/mod.rs index 7d6a413a43..ded233be4c 100644 --- a/c2rust-transpile/src/cfg/mod.rs +++ b/c2rust-transpile/src/cfg/mod.rs @@ -34,7 +34,7 @@ use std::ops::Index; use std::rc::Rc; use std::{fmt, io}; use syn::Lit; -use syn::{spanned::Spanned, Arm, Expr, Pat, Stmt}; +use syn::{punctuated::Punctuated, spanned::Spanned, Arm, Expr, Pat, Stmt}; use failure::format_err; use indexmap::indexset; @@ -433,6 +433,7 @@ impl GenTerminator> { pub struct SwitchCases { cases: Vec<(Pat, Label)>, default: Option