Skip to content

Commit

Permalink
Ensure subclasses gain destructors from supers.
Browse files Browse the repository at this point in the history
Previously we didn't populate a destructor (Drop) trait for a synthesized
subclass even if the superclass had a destructor. We should have done.

The general problem of derived classes being unaware of their superclass
destructors is #988. The present fix only applies to synthesized subclasses.

As well as being incorrect, this also prevented subclasses gaining a
make_unique method.
  • Loading branch information
adetaylor committed Apr 1, 2022
1 parent 134687d commit da2f776
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
20 changes: 18 additions & 2 deletions engine/src/conversion/analysis/fun/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ use self::{
implicit_constructors::{find_constructors_present, ItemsFound},
overload_tracker::OverloadTracker,
subclass::{
create_subclass_constructor, create_subclass_fn_wrapper, create_subclass_function,
create_subclass_trait_item,
create_subclass_constructor, create_subclass_destructor, create_subclass_fn_wrapper,
create_subclass_function, create_subclass_trait_item,
},
};

Expand Down Expand Up @@ -565,6 +565,22 @@ impl<'a> FnAnalyzer<'a> {
);
}
}
FnKind::TraitMethod {
kind: TraitMethodKind::Destructor,
impl_for: sup,
..
} => {
for sub in self.subclasses_by_superclass(sup) {
let (subclass_destructor_func, subclass_destructor_name) =
create_subclass_destructor(sub, &fun);
self.analyze_and_add(
subclass_destructor_name.clone(),
subclass_destructor_func.clone(),
&mut results,
TypeConversionSophistication::Regular,
);
}
}
_ => {}
}

Expand Down
35 changes: 35 additions & 0 deletions engine/src/conversion/analysis/fun/subclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,38 @@ pub(super) fn create_subclass_constructor(
);
(maybe_wrap, subclass_constructor_name)
}

pub(super) fn create_subclass_destructor(
sub: SubclassName,
fun: &FuncToConvert,
) -> (Box<FuncToConvert>, ApiName) {
let cpp = sub.cpp();
let subclass_destructor_name = make_ident(format!(
"{}_{}_destructor",
cpp.get_final_item(),
cpp.get_final_item()
));
let maybe_wrap = Box::new(FuncToConvert {
ident: subclass_destructor_name.clone(),
doc_attrs: fun.doc_attrs.clone(),
inputs: fun.inputs.clone(),
output: fun.output.clone(),
vis: fun.vis.clone(),
virtualness: Virtualness::None,
cpp_vis: CppVisibility::Public,
special_member: fun.special_member.clone(),
original_name: None,
unused_template_param: fun.unused_template_param,
references: fun.references.clone(),
synthesized_this_type: Some(cpp.clone()),
self_ty: Some(cpp),
add_to_trait: None,
is_deleted: fun.is_deleted,
synthetic_cpp: None,
provenance: Provenance::SynthesizedOther,
});
let cpp_name = format!("{}_destructor", sub.cpp().get_final_item().to_string());
let subclass_destructor_name =
ApiName::new_with_cpp_name(&Namespace::new(), subclass_destructor_name, Some(cpp_name));
(maybe_wrap, subclass_destructor_name)
}

0 comments on commit da2f776

Please sign in to comment.