Skip to content

Commit 437b202

Browse files
committed
factor out maybe_indirection_for_unsized
1 parent 2862f08 commit 437b202

File tree

1 file changed

+47
-32
lines changed
  • compiler/rustc_trait_selection/src/traits/error_reporting

1 file changed

+47
-32
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+47-32
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder,
1616
use rustc_hir as hir;
1717
use rustc_hir::def_id::DefId;
1818
use rustc_hir::intravisit::Visitor;
19+
use rustc_hir::GenericParam;
20+
use rustc_hir::Item;
1921
use rustc_hir::Node;
2022
use rustc_middle::mir::abstract_const::NotConstEvaluatable;
2123
use rustc_middle::ty::error::ExpectedFound;
@@ -1095,6 +1097,13 @@ trait InferCtxtPrivExt<'tcx> {
10951097
node: Node<'hir>,
10961098
);
10971099

1100+
fn maybe_indirection_for_unsized(
1101+
&self,
1102+
err: &mut DiagnosticBuilder<'tcx>,
1103+
item: &'hir Item<'hir>,
1104+
param: &'hir GenericParam<'hir>,
1105+
) -> bool;
1106+
10981107
fn is_recursive_obligation(
10991108
&self,
11001109
obligated_types: &mut Vec<&ty::TyS<'tcx>>,
@@ -1821,38 +1830,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
18211830
..
18221831
},
18231832
) => {
1824-
// Suggesting `T: ?Sized` is only valid in an ADT if `T` is only used in a
1825-
// borrow. `struct S<'a, T: ?Sized>(&'a T);` is valid, `struct S<T: ?Sized>(T);`
1826-
// is not.
1827-
let mut visitor = FindTypeParam {
1828-
param: param.name.ident().name,
1829-
invalid_spans: vec![],
1830-
nested: false,
1831-
};
1832-
visitor.visit_item(item);
1833-
if !visitor.invalid_spans.is_empty() {
1834-
let mut multispan: MultiSpan = param.span.into();
1835-
multispan.push_span_label(
1836-
param.span,
1837-
format!("this could be changed to `{}: ?Sized`...", param.name.ident()),
1838-
);
1839-
for sp in visitor.invalid_spans {
1840-
multispan.push_span_label(
1841-
sp,
1842-
format!(
1843-
"...if indirection were used here: `Box<{}>`",
1844-
param.name.ident(),
1845-
),
1846-
);
1847-
}
1848-
err.span_help(
1849-
multispan,
1850-
&format!(
1851-
"you could relax the implicit `Sized` bound on `{T}` if it were \
1852-
used through indirection like `&{T}` or `Box<{T}>`",
1853-
T = param.name.ident(),
1854-
),
1855-
);
1833+
if self.maybe_indirection_for_unsized(err, item, param) {
18561834
return;
18571835
}
18581836
}
@@ -1872,6 +1850,43 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
18721850
}
18731851
}
18741852

1853+
fn maybe_indirection_for_unsized(
1854+
&self,
1855+
err: &mut DiagnosticBuilder<'tcx>,
1856+
item: &'hir Item<'hir>,
1857+
param: &'hir GenericParam<'hir>,
1858+
) -> bool {
1859+
// Suggesting `T: ?Sized` is only valid in an ADT if `T` is only used in a
1860+
// borrow. `struct S<'a, T: ?Sized>(&'a T);` is valid, `struct S<T: ?Sized>(T);`
1861+
// is not.
1862+
let mut visitor =
1863+
FindTypeParam { param: param.name.ident().name, invalid_spans: vec![], nested: false };
1864+
visitor.visit_item(item);
1865+
if !visitor.invalid_spans.is_empty() {
1866+
let mut multispan: MultiSpan = param.span.into();
1867+
multispan.push_span_label(
1868+
param.span,
1869+
format!("this could be changed to `{}: ?Sized`...", param.name.ident()),
1870+
);
1871+
for sp in visitor.invalid_spans {
1872+
multispan.push_span_label(
1873+
sp,
1874+
format!("...if indirection were used here: `Box<{}>`", param.name.ident()),
1875+
);
1876+
}
1877+
err.span_help(
1878+
multispan,
1879+
&format!(
1880+
"you could relax the implicit `Sized` bound on `{T}` if it were \
1881+
used through indirection like `&{T}` or `Box<{T}>`",
1882+
T = param.name.ident(),
1883+
),
1884+
);
1885+
return true;
1886+
}
1887+
false
1888+
}
1889+
18751890
fn is_recursive_obligation(
18761891
&self,
18771892
obligated_types: &mut Vec<&ty::TyS<'tcx>>,

0 commit comments

Comments
 (0)