check where clause before suggesting unsized
This commit is contained in:
parent
b053550847
commit
c9fcbda389
3 changed files with 45 additions and 0 deletions
|
@ -14,6 +14,7 @@ use crate::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
|
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::GenericParam;
|
use rustc_hir::GenericParam;
|
||||||
|
@ -2009,6 +2010,24 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
Some(param) => param,
|
Some(param) => param,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
let param_def_id = self.tcx.hir().local_def_id(param.hir_id).to_def_id();
|
||||||
|
let preds = generics.where_clause.predicates.iter();
|
||||||
|
let explicitly_sized = preds
|
||||||
|
.filter_map(|pred| match pred {
|
||||||
|
hir::WherePredicate::BoundPredicate(bp) => Some(bp),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.flat_map(|bp| match bp.bounded_ty.kind {
|
||||||
|
hir::TyKind::Path(hir::QPath::Resolved(
|
||||||
|
None,
|
||||||
|
&hir::Path { res: Res::Def(DefKind::TyParam, def_id), .. },
|
||||||
|
)) if def_id == param_def_id => bp.bounds,
|
||||||
|
_ => &[][..],
|
||||||
|
})
|
||||||
|
.any(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) == sized_trait);
|
||||||
|
if explicitly_sized {
|
||||||
|
return;
|
||||||
|
}
|
||||||
debug!("maybe_suggest_unsized_generics: param={:?}", param);
|
debug!("maybe_suggest_unsized_generics: param={:?}", param);
|
||||||
match node {
|
match node {
|
||||||
hir::Node::Item(
|
hir::Node::Item(
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Regression test for #85945: Don't suggest `?Sized` bound if an explicit
|
||||||
|
// `Sized` bound is already in a `where` clause.
|
||||||
|
fn foo<T>(_: &T) where T: Sized {}
|
||||||
|
fn bar() { foo(""); }
|
||||||
|
//~^ERROR the size for values of type
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
|
--> $DIR/issue-85945-check-where-clause-before-suggesting-unsized.rs:4:16
|
||||||
|
|
|
||||||
|
LL | fn bar() { foo(""); }
|
||||||
|
| --- ^^ doesn't have a size known at compile-time
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
note: required by a bound in `foo`
|
||||||
|
--> $DIR/issue-85945-check-where-clause-before-suggesting-unsized.rs:3:8
|
||||||
|
|
|
||||||
|
LL | fn foo<T>(_: &T) where T: Sized {}
|
||||||
|
| ^ required by this bound in `foo`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue