1
Fork 0

Call skip_binder or no_bound_vars before self_ty

This commit is contained in:
Dylan MacKenzie 2020-05-23 11:12:06 -07:00
parent eaa57cfb71
commit b4e06b9e88
6 changed files with 43 additions and 23 deletions

View file

@ -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;

View file

@ -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`

View file

@ -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;
} }
} }

View file

@ -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

View file

@ -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() {

View file

@ -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(),
)); ));
} }