Skip to content

Commit b9ece48

Browse files
committed
apply refactoring suggestion
1 parent 201617e commit b9ece48

File tree

1 file changed

+71
-64
lines changed

1 file changed

+71
-64
lines changed

clippy_lints/src/new_without_default.rs

Lines changed: 71 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -135,79 +135,86 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
135135
if impl_item.span.in_external_macro(cx.sess().source_map()) {
136136
return;
137137
}
138-
if let hir::ImplItemKind::Fn(ref sig, body_id) = impl_item.kind {
139-
let name = impl_item.ident.name;
140-
let id = impl_item.owner_id;
141-
if sig.header.is_unsafe() {
142-
// can't be implemented for unsafe new
143-
return;
144-
}
145-
if cx.tcx.is_doc_hidden(impl_item.owner_id.def_id) {
146-
// shouldn't be implemented when it is hidden in docs
147-
return;
148-
}
149-
if !impl_item.generics.params.is_empty() {
150-
// when the result of `new()` depends on a parameter we should not require
151-
// an impl of `Default`
152-
return;
138+
let hir::ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else {
139+
continue;
140+
};
141+
142+
let name = impl_item.ident.name;
143+
let id = impl_item.owner_id;
144+
if sig.header.is_unsafe() {
145+
// can't be implemented for unsafe new
146+
return;
147+
}
148+
if cx.tcx.is_doc_hidden(impl_item.owner_id.def_id) {
149+
// shouldn't be implemented when it is hidden in docs
150+
return;
151+
}
152+
if !impl_item.generics.params.is_empty() {
153+
// when the result of `new()` depends on a parameter we should not require
154+
// an impl of `Default`
155+
return;
156+
}
157+
if sig.decl.inputs.is_empty()
158+
&& name == sym::new
159+
&& let self_def_id = cx.tcx.hir().get_parent_item(id.into())
160+
&& let self_ty = cx.tcx.type_of(self_def_id).instantiate_identity()
161+
&& self_ty == return_ty(cx, id)
162+
&& let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)
163+
{
164+
if self.impling_types.is_none() {
165+
let mut impls = HirIdMap::default();
166+
cx.tcx.for_each_impl(default_trait_id, |d| {
167+
let ty = cx.tcx.type_of(d).instantiate_identity();
168+
if let Some(ty_def) = ty.ty_adt_def() {
169+
if let Some(local_def_id) = ty_def.did().as_local() {
170+
impls.insert(
171+
cx.tcx.local_def_id_to_hir_id(local_def_id),
172+
if cx.tcx.is_builtin_derived(d) {
173+
DefaultType::AutoDerived
174+
} else {
175+
DefaultType::Manual
176+
},
177+
);
178+
}
179+
}
180+
});
181+
self.impling_types = Some(impls);
153182
}
154-
if sig.decl.inputs.is_empty()
155-
&& name == sym::new
156-
&& let self_def_id = cx.tcx.hir().get_parent_item(id.into())
157-
&& let self_ty = cx.tcx.type_of(self_def_id).instantiate_identity()
158-
&& self_ty == return_ty(cx, id)
159-
&& let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)
183+
184+
// Check if a Default implementation exists for the Self type, regardless of generics
185+
let default_type = if let Some(ref impling_types) = self.impling_types
186+
&& let self_def = cx.tcx.type_of(self_def_id).instantiate_identity()
187+
&& let Some(self_def) = self_def.ty_adt_def()
188+
&& let Some(self_local_did) = self_def.did().as_local()
160189
{
161-
if self.impling_types.is_none() {
162-
let mut impls = HirIdMap::default();
163-
cx.tcx.for_each_impl(default_trait_id, |d| {
164-
let ty = cx.tcx.type_of(d).instantiate_identity();
165-
if let Some(ty_def) = ty.ty_adt_def() {
166-
if let Some(local_def_id) = ty_def.did().as_local() {
167-
impls.insert(
168-
cx.tcx.local_def_id_to_hir_id(local_def_id),
169-
if cx.tcx.is_builtin_derived(d) {
170-
DefaultType::AutoDerived
171-
} else {
172-
DefaultType::Manual
173-
},
174-
);
175-
}
176-
}
177-
});
178-
self.impling_types = Some(impls);
179-
}
190+
impling_types.get(&cx.tcx.local_def_id_to_hir_id(self_local_did))
191+
} else {
192+
None
193+
};
180194

181-
let mut default_type = None;
182-
// Check if a Default implementation exists for the Self type, regardless of generics
183-
if let Some(ref impling_types) = self.impling_types
184-
&& let self_def = cx.tcx.type_of(self_def_id).instantiate_identity()
185-
&& let Some(self_def) = self_def.ty_adt_def()
186-
&& let Some(self_local_did) = self_def.did().as_local()
187-
{
188-
let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did);
189-
default_type = impling_types.get(&self_id);
190-
if let Some(DefaultType::Manual) = default_type {
191-
// both `new` and `default` are manually implemented
192-
return;
195+
match default_type {
196+
Some(DefaultType::AutoDerived) => {
197+
if let hir::ExprKind::Block(block, _) = cx.tcx.hir_body(body_id).value.kind
198+
&& !is_unit_struct(cx, self_ty)
199+
// TODO: handle generics
200+
&& generics.params.is_empty()
201+
// this type has an automatically derived `Default` implementation
202+
// check if `new` and `default` are equivalent
203+
&& let Some(span) = check_block_calls_default(cx, block)
204+
{
205+
suggest_default_mismatch_new(cx, span, id, block, self_ty, impl_self_ty);
193206
}
194-
}
195-
196-
if default_type.is_none() {
207+
},
208+
Some(DefaultType::Manual) => {
209+
// both `new` and `default` are manually implemented
210+
},
211+
None => {
197212
// there are no `Default` implementations for this type
198213
if !cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id) {
199214
return;
200215
}
201216
suggest_new_without_default(cx, item, impl_item, id, self_ty, generics, impl_self_ty);
202-
} else if let hir::ExprKind::Block(block, _) = cx.tcx.hir_body(body_id).value.kind
203-
&& !is_unit_struct(cx, self_ty)
204-
// TODO: handle generics
205-
&& generics.params.is_empty()
206-
// check if `new` and `default` are equivalent
207-
&& let Some(span) = check_block_calls_default(cx, block)
208-
{
209-
suggest_default_mismatch_new(cx, span, id, block, self_ty, impl_self_ty);
210-
}
217+
},
211218
}
212219
}
213220
}

0 commit comments

Comments
 (0)