Skip to content

Commit b8850df

Browse files
committed
Suggest removing Box::new
1 parent af00ff2 commit b8850df

File tree

5 files changed

+58
-5
lines changed

5 files changed

+58
-5
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,6 +2955,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
29552955
)
29562956
{
29572957
let deref_kind = if checked_ty.is_box() {
2958+
// detect Box::new(..)
2959+
if let ExprKind::Call(box_new, [arg]) = expr.kind
2960+
&& let ExprKind::Path(qpath) = &box_new.kind
2961+
&& let Res::Def(DefKind::AssocFn, fn_id) =
2962+
self.typeck_results.borrow().qpath_res(qpath, box_new.hir_id)
2963+
&& let Some(impl_id) = self.tcx.inherent_impl_of_assoc(fn_id)
2964+
&& self.tcx.type_of(impl_id).skip_binder().is_box()
2965+
&& self.tcx.item_name(fn_id) == sym::new
2966+
&& let source_map = self.tcx.sess.source_map()
2967+
&& let Ok(paren) =
2968+
source_map.span_extend_prev_n_chars(expr.span.shrink_to_hi(), 1)
2969+
{
2970+
return Some((
2971+
vec![
2972+
(expr.span.until(arg.span), "".to_string()),
2973+
(paren, "".to_string()),
2974+
],
2975+
"consider removing the Box".to_string(),
2976+
Applicability::MachineApplicable,
2977+
false,
2978+
false,
2979+
));
2980+
}
29582981
"unboxing the value"
29592982
} else if checked_ty.is_ref() {
29602983
"dereferencing the borrow"

compiler/rustc_span/src/source_map.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ impl SourceMap {
551551
/// the slice for the beginning of the span and an index in the slice for the end of the span.
552552
pub fn span_to_source<F, T>(&self, sp: Span, extract_source: F) -> Result<T, SpanSnippetError>
553553
where
554-
F: Fn(&str, usize, usize) -> Result<T, SpanSnippetError>,
554+
F: FnOnce(&str, usize, usize) -> Result<T, SpanSnippetError>,
555555
{
556556
let local_begin = self.lookup_byte_offset(sp.lo());
557557
let local_end = self.lookup_byte_offset(sp.hi());
@@ -724,7 +724,7 @@ impl SourceMap {
724724
pub fn span_extend_prev_while(
725725
&self,
726726
span: Span,
727-
f: impl Fn(char) -> bool,
727+
mut f: impl FnMut(char) -> bool,
728728
) -> Result<Span, SpanSnippetError> {
729729
self.span_to_source(span, |s, start, _end| {
730730
let n = s[..start]
@@ -735,6 +735,12 @@ impl SourceMap {
735735
})
736736
}
737737

738+
/// Extends the given `Span` to include the previous n characters
739+
pub fn span_extend_prev_n_chars(&self, span: Span, n: usize) -> Result<Span, SpanSnippetError> {
740+
let mut iter = 0..n;
741+
self.span_extend_prev_while(span, |_c| iter.next().is_some())
742+
}
743+
738744
/// Extends the given `Span` to just before the next occurrence of `c`.
739745
pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
740746
if let Ok(next_source) = self.span_to_next_source(sp) {

tests/ui/coercion/coerce-block-tail.stderr

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ LL | let _: &i32 = & { Box::new(1i32) };
66
|
77
= note: expected type `i32`
88
found struct `Box<i32>`
9-
help: consider unboxing the value
9+
help: consider removing the Box
10+
|
11+
LL - let _: &i32 = & { Box::new(1i32) };
12+
LL + let _: &i32 = & { 1i32 };
1013
|
11-
LL | let _: &i32 = & { *Box::new(1i32) };
12-
| +
1314

1415
error: aborting due to 1 previous error
1516

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
let _: String = Box::new(String::new());
3+
//~^ ERROR mismatched types
4+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/coerce-box-new-to-unboxed.rs:2:21
3+
|
4+
LL | let _: String = Box::new(String::new());
5+
| ------ ^^^^^^^^^^^^^^^^^^^^^^^ expected `String`, found `Box<String>`
6+
| |
7+
| expected due to this
8+
|
9+
= note: expected struct `String`
10+
found struct `Box<String>`
11+
help: consider removing the Box
12+
|
13+
LL - let _: String = Box::new(String::new());
14+
LL + let _: String = String::new();
15+
|
16+
17+
error: aborting due to 1 previous error
18+
19+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)