Skip to content

Commit b0a6e51

Browse files
authored
refactor: Support associated constants in reorganize_definitions (#1746)
- Fixes #1660 This was quite tricky to implement, but it's now working and #1659 passes its tests with these additions. Only `const` associated items are supported. `type` items could be added later, but `fn` is probably never going to work because they are too complex to test for equivalence.
2 parents 80bb8c3 + a7c55c3 commit b0a6e51

5 files changed

Lines changed: 374 additions & 26 deletions

File tree

c2rust-refactor/src/context.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::ops::Deref;
44

55
use rustc_ast::ptr::P;
66
use rustc_ast::{
7-
Expr, ExprKind, FnDecl, FnRetTy, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId, Path,
8-
QSelf, UseTreeKind, DUMMY_NODE_ID,
7+
AssocItem, Expr, ExprKind, FnDecl, FnRetTy, ForeignItem, ForeignItemKind, Item, ItemKind,
8+
NodeId, Path, QSelf, UseTreeKind, DUMMY_NODE_ID,
99
};
1010
use rustc_data_structures::fx::FxHashMap;
1111
use rustc_errors::{DiagnosticBuilder, Level};
@@ -1073,6 +1073,16 @@ impl<'a, 'tcx, 'b> TypeCompare<'a, 'tcx, 'b> {
10731073
pub fn compatible_types(&self, item1: &Item, item2: &Item, match_vis: bool) -> bool {
10741074
use rustc_ast::ItemKind::*;
10751075
match (&item1.kind, &item2.kind) {
1076+
(Impl(box ref impl1), Impl(box ref impl2)) => {
1077+
if impl1.items.len() != impl2.items.len() {
1078+
return false;
1079+
}
1080+
1081+
(impl1.items.iter())
1082+
.zip(impl2.items.iter())
1083+
.all(|(item1, item2)| self.compatible_assoc_items(item1, item2, match_vis))
1084+
}
1085+
10761086
// * Assure that these two items are in fact of the same type, just to be safe.
10771087
(TyAlias(box ref ta1), TyAlias(box ref ta2)) => {
10781088
match (
@@ -1227,6 +1237,40 @@ impl<'a, 'tcx, 'b> TypeCompare<'a, 'tcx, 'b> {
12271237
}
12281238
}
12291239

1240+
pub fn compatible_assoc_items(
1241+
&self,
1242+
item1: &AssocItem,
1243+
item2: &AssocItem,
1244+
match_vis: bool,
1245+
) -> bool {
1246+
use rustc_ast::AssocItemKind::*;
1247+
1248+
// Unlike for regular items, associated items must also match by name.
1249+
if item1.ident.as_str() != item2.ident.as_str() {
1250+
return false;
1251+
}
1252+
1253+
match (&item1.kind, &item2.kind) {
1254+
(Const(def1, ty1, expr1), Const(def2, ty2, expr2)) => match (
1255+
self.cx.opt_node_type(item1.id),
1256+
self.cx.opt_node_type(item2.id),
1257+
) {
1258+
(Some(ty1), Some(ty2)) => {
1259+
self.structural_eq_tys(ty1, ty2)
1260+
&& expr1.unnamed_equiv(expr2)
1261+
&& def1.unnamed_equiv(def2)
1262+
}
1263+
_ => {
1264+
self.structural_eq_ast_tys(ty1, ty2, match_vis)
1265+
&& expr1.unnamed_equiv(expr2)
1266+
&& def1.unnamed_equiv(def2)
1267+
}
1268+
},
1269+
1270+
_ => false,
1271+
}
1272+
}
1273+
12301274
/// Compare two function declarations for equivalent argument and return types,
12311275
/// ignoring argument names.
12321276
pub fn compatible_fn_prototypes(&self, decl1: &FnDecl, decl2: &FnDecl) -> bool {

0 commit comments

Comments
 (0)