check FnDef
return type for WF
This commit is contained in:
parent
4fd4797c26
commit
2b67f0104a
6 changed files with 138 additions and 44 deletions
|
@ -647,6 +647,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
fn visit_ty(&mut self, t: <TyCtxt<'tcx> as ty::Interner>::Ty) -> Self::Result {
|
||||
debug!("wf bounds for t={:?} t.kind={:#?}", t, t.kind());
|
||||
|
||||
let tcx = self.tcx();
|
||||
|
||||
match *t.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
|
@ -707,6 +709,16 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ty::FnDef(did, args) => {
|
||||
// HACK: Check the return type of function definitions for
|
||||
// well-formedness to mostly fix #84533. This is still not
|
||||
// perfect and there may be ways to abuse the fact that we
|
||||
// ignore requirements with escaping bound vars. That's a
|
||||
// more general issue however.
|
||||
//
|
||||
// FIXME(eddyb) add the type to `walker` instead of recursing.
|
||||
let fn_sig = tcx.fn_sig(did).instantiate(tcx, args);
|
||||
fn_sig.output().skip_binder().visit_with(self);
|
||||
|
||||
let obligations = self.nominal_obligations(did, args);
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
|
@ -716,7 +728,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
if !r.has_escaping_bound_vars() && !rty.has_escaping_bound_vars() {
|
||||
let cause = self.cause(traits::ReferenceOutlivesReferent(t));
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
tcx,
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
|
@ -805,12 +817,12 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
// obligations that don't refer to Self and
|
||||
// checking those
|
||||
|
||||
let defer_to_coercion = self.tcx().features().object_safe_for_dispatch;
|
||||
let defer_to_coercion = tcx.features().object_safe_for_dispatch;
|
||||
|
||||
if !defer_to_coercion {
|
||||
if let Some(principal) = data.principal_def_id() {
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
tcx,
|
||||
self.cause(traits::WellFormed(None)),
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
|
@ -835,7 +847,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
ty::Infer(_) => {
|
||||
let cause = self.cause(traits::WellFormed(None));
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
tcx,
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
|
@ -850,6 +862,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_const(&mut self, c: <TyCtxt<'tcx> as ty::Interner>::Const) -> Self::Result {
|
||||
let tcx = self.tcx();
|
||||
|
||||
match c.kind() {
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
if !c.has_escaping_bound_vars() {
|
||||
|
@ -861,7 +875,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
));
|
||||
let cause = self.cause(traits::WellFormed(None));
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
tcx,
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
|
@ -873,7 +887,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
let cause = self.cause(traits::WellFormed(None));
|
||||
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
tcx,
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
|
@ -895,7 +909,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
|||
));
|
||||
let cause = self.cause(traits::WellFormed(None));
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
tcx,
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue