Call skip_binder
or no_bound_vars
before self_ty
This commit is contained in:
parent
eaa57cfb71
commit
b4e06b9e88
6 changed files with 43 additions and 23 deletions
|
@ -289,7 +289,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
(
|
(
|
||||||
Some(format!(
|
Some(format!(
|
||||||
"`?` couldn't convert the error to `{}`",
|
"`?` couldn't convert the error to `{}`",
|
||||||
trait_ref.self_ty(),
|
trait_ref.skip_binder().self_ty(),
|
||||||
)),
|
)),
|
||||||
Some(
|
Some(
|
||||||
"the question mark operation (`?`) implicitly performs a \
|
"the question mark operation (`?`) implicitly performs a \
|
||||||
|
@ -339,7 +339,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
if let Some(ret_span) = self.return_type_span(obligation) {
|
if let Some(ret_span) = self.return_type_span(obligation) {
|
||||||
err.span_label(
|
err.span_label(
|
||||||
ret_span,
|
ret_span,
|
||||||
&format!("expected `{}` because of this", trait_ref.self_ty()),
|
&format!(
|
||||||
|
"expected `{}` because of this",
|
||||||
|
trait_ref.skip_binder().self_ty()
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,7 +355,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
"{}the trait `{}` is not implemented for `{}`",
|
"{}the trait `{}` is not implemented for `{}`",
|
||||||
pre_message,
|
pre_message,
|
||||||
trait_ref.print_only_trait_path(),
|
trait_ref.print_only_trait_path(),
|
||||||
trait_ref.self_ty(),
|
trait_ref.skip_binder().self_ty(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -642,7 +645,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let found_trait_ty = found_trait_ref.self_ty();
|
let found_trait_ty = match found_trait_ref.self_ty().no_bound_vars() {
|
||||||
|
Some(ty) => ty,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
let found_did = match found_trait_ty.kind {
|
let found_did = match found_trait_ty.kind {
|
||||||
ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
|
ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
|
||||||
|
@ -1359,11 +1365,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
) {
|
) {
|
||||||
let get_trait_impl = |trait_def_id| {
|
let get_trait_impl = |trait_def_id| {
|
||||||
let mut trait_impl = None;
|
let mut trait_impl = None;
|
||||||
self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| {
|
self.tcx.for_each_relevant_impl(
|
||||||
|
trait_def_id,
|
||||||
|
trait_ref.skip_binder().self_ty(),
|
||||||
|
|impl_def_id| {
|
||||||
if trait_impl.is_none() {
|
if trait_impl.is_none() {
|
||||||
trait_impl = Some(impl_def_id);
|
trait_impl = Some(impl_def_id);
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
trait_impl
|
trait_impl
|
||||||
};
|
};
|
||||||
let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
|
let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
|
||||||
|
@ -1434,7 +1444,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
let mut err = match predicate.kind() {
|
let mut err = match predicate.kind() {
|
||||||
ty::PredicateKind::Trait(ref data, _) => {
|
ty::PredicateKind::Trait(ref data, _) => {
|
||||||
let trait_ref = data.to_poly_trait_ref();
|
let trait_ref = data.to_poly_trait_ref();
|
||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = trait_ref.skip_binder().self_ty();
|
||||||
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref);
|
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref);
|
||||||
|
|
||||||
if predicate.references_error() {
|
if predicate.references_error() {
|
||||||
|
@ -1552,7 +1562,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Projection(ref data) => {
|
ty::PredicateKind::Projection(ref data) => {
|
||||||
let trait_ref = data.to_poly_trait_ref(self.tcx);
|
let trait_ref = data.to_poly_trait_ref(self.tcx);
|
||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = trait_ref.skip_binder().self_ty();
|
||||||
let ty = data.skip_binder().ty;
|
let ty = data.skip_binder().ty;
|
||||||
if predicate.references_error() {
|
if predicate.references_error() {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -318,7 +318,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
body_id: hir::HirId,
|
body_id: hir::HirId,
|
||||||
) {
|
) {
|
||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = trait_ref.skip_binder().self_ty();
|
||||||
let (param_ty, projection) = match &self_ty.kind {
|
let (param_ty, projection) = match &self_ty.kind {
|
||||||
ty::Param(_) => (true, None),
|
ty::Param(_) => (true, None),
|
||||||
ty::Projection(projection) => (false, Some(projection)),
|
ty::Projection(projection) => (false, Some(projection)),
|
||||||
|
@ -524,7 +524,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
|
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
|
||||||
points_at_arg: bool,
|
points_at_arg: bool,
|
||||||
) {
|
) {
|
||||||
let self_ty = trait_ref.self_ty();
|
let self_ty = match trait_ref.self_ty().no_bound_vars() {
|
||||||
|
None => return,
|
||||||
|
Some(ty) => ty,
|
||||||
|
};
|
||||||
|
|
||||||
let (def_id, output_ty, callable) = match self_ty.kind {
|
let (def_id, output_ty, callable) = match self_ty.kind {
|
||||||
ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig().output(), "closure"),
|
ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig().output(), "closure"),
|
||||||
ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
|
ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
|
||||||
|
@ -707,7 +711,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut suggested_ty = trait_ref.self_ty();
|
let mut suggested_ty = match trait_ref.self_ty().no_bound_vars() {
|
||||||
|
Some(ty) => ty,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
for refs_remaining in 0..refs_number {
|
for refs_remaining in 0..refs_number {
|
||||||
if let ty::Ref(_, inner_ty, _) = suggested_ty.kind {
|
if let ty::Ref(_, inner_ty, _) = suggested_ty.kind {
|
||||||
|
@ -829,6 +836,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
|
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
|
||||||
) {
|
) {
|
||||||
|
let is_empty_tuple =
|
||||||
|
|ty: ty::Binder<Ty<'_>>| ty.skip_binder().kind == ty::Tuple(ty::List::empty());
|
||||||
|
|
||||||
let hir = self.tcx.hir();
|
let hir = self.tcx.hir();
|
||||||
let parent_node = hir.get_parent_node(obligation.cause.body_id);
|
let parent_node = hir.get_parent_node(obligation.cause.body_id);
|
||||||
let node = hir.find(parent_node);
|
let node = hir.find(parent_node);
|
||||||
|
@ -840,7 +850,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
if let hir::ExprKind::Block(blk, _) = &body.value.kind {
|
if let hir::ExprKind::Block(blk, _) = &body.value.kind {
|
||||||
if sig.decl.output.span().overlaps(span)
|
if sig.decl.output.span().overlaps(span)
|
||||||
&& blk.expr.is_none()
|
&& blk.expr.is_none()
|
||||||
&& "()" == &trait_ref.self_ty().to_string()
|
&& is_empty_tuple(trait_ref.self_ty())
|
||||||
{
|
{
|
||||||
// FIXME(estebank): When encountering a method with a trait
|
// FIXME(estebank): When encountering a method with a trait
|
||||||
// bound not satisfied in the return type with a body that has
|
// bound not satisfied in the return type with a body that has
|
||||||
|
@ -1271,7 +1281,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
ObligationCauseCode::DerivedObligation(derived_obligation)
|
ObligationCauseCode::DerivedObligation(derived_obligation)
|
||||||
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation)
|
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation)
|
||||||
| ObligationCauseCode::ImplDerivedObligation(derived_obligation) => {
|
| ObligationCauseCode::ImplDerivedObligation(derived_obligation) => {
|
||||||
let ty = derived_obligation.parent_trait_ref.self_ty();
|
let ty = derived_obligation.parent_trait_ref.skip_binder().self_ty();
|
||||||
debug!(
|
debug!(
|
||||||
"maybe_note_obligation_cause_for_async_await: \
|
"maybe_note_obligation_cause_for_async_await: \
|
||||||
parent_trait_ref={:?} self_ty.kind={:?}",
|
parent_trait_ref={:?} self_ty.kind={:?}",
|
||||||
|
@ -1911,7 +1921,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let impls_future = self.tcx.type_implements_trait((
|
let impls_future = self.tcx.type_implements_trait((
|
||||||
future_trait,
|
future_trait,
|
||||||
self_ty,
|
self_ty.skip_binder(),
|
||||||
ty::List::empty(),
|
ty::List::empty(),
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
));
|
));
|
||||||
|
@ -1927,7 +1937,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
let projection_ty = ty::ProjectionTy {
|
let projection_ty = ty::ProjectionTy {
|
||||||
// `T`
|
// `T`
|
||||||
substs: self.tcx.mk_substs_trait(
|
substs: self.tcx.mk_substs_trait(
|
||||||
trait_ref.self_ty(),
|
trait_ref.self_ty().skip_binder(),
|
||||||
self.fresh_substs_for_item(span, item_def_id),
|
self.fresh_substs_for_item(span, item_def_id),
|
||||||
),
|
),
|
||||||
// `Future::Output`
|
// `Future::Output`
|
||||||
|
|
|
@ -496,7 +496,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String>
|
||||||
for (p, _) in predicates {
|
for (p, _) in predicates {
|
||||||
if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() {
|
if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() {
|
||||||
if Some(poly_trait_ref.def_id()) == sized_trait {
|
if Some(poly_trait_ref.def_id()) == sized_trait {
|
||||||
types_without_default_bounds.remove(poly_trait_ref.self_ty());
|
types_without_default_bounds.remove(poly_trait_ref.self_ty().skip_binder());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3812,7 +3812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
expected_vid: ty::TyVid,
|
expected_vid: ty::TyVid,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let self_ty = self.shallow_resolve(trait_ref.self_ty());
|
let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
|
||||||
debug!(
|
debug!(
|
||||||
"self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
|
"self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
|
||||||
trait_ref, self_ty, expected_vid
|
trait_ref, self_ty, expected_vid
|
||||||
|
|
|
@ -500,7 +500,7 @@ impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
|
||||||
fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
|
fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
|
||||||
let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
|
let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
|
||||||
WherePredicate::BoundPredicate {
|
WherePredicate::BoundPredicate {
|
||||||
ty: poly_trait_ref.self_ty().clean(cx),
|
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
|
||||||
bounds: vec![poly_trait_ref.clean(cx)],
|
bounds: vec![poly_trait_ref.clean(cx)],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -755,7 +755,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
|
||||||
let mut projection = None;
|
let mut projection = None;
|
||||||
let param_idx = (|| {
|
let param_idx = (|| {
|
||||||
if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
|
if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
|
||||||
if let ty::Param(param) = trait_ref.self_ty().kind {
|
if let ty::Param(param) = trait_ref.skip_binder().self_ty().kind {
|
||||||
return Some(param.index);
|
return Some(param.index);
|
||||||
}
|
}
|
||||||
} else if let Some(outlives) = p.to_opt_type_outlives() {
|
} else if let Some(outlives) = p.to_opt_type_outlives() {
|
||||||
|
|
|
@ -95,7 +95,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FutureNotSend {
|
||||||
let trait_ref = trait_pred.to_poly_trait_ref();
|
let trait_ref = trait_pred.to_poly_trait_ref();
|
||||||
db.note(&*format!(
|
db.note(&*format!(
|
||||||
"`{}` doesn't implement `{}`",
|
"`{}` doesn't implement `{}`",
|
||||||
trait_ref.self_ty(),
|
trait_ref.skip_binder().self_ty(),
|
||||||
trait_ref.print_only_trait_path(),
|
trait_ref.print_only_trait_path(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue