Always check predicates in can_coerce
This only changed two tests and I consider both changes an improvement.
This commit is contained in:
parent
5c14433c00
commit
485ae9f2c0
@ -934,20 +934,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// Same as `try_coerce()`, but without side-effects.
|
||||
///
|
||||
/// Returns false if the coercion creates any obligations that result in
|
||||
/// errors.
|
||||
pub fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
|
||||
let source = self.resolve_vars_with_obligations(expr_ty);
|
||||
debug!("coercion::can({:?} -> {:?})", source, target);
|
||||
|
||||
let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable);
|
||||
// We don't ever need two-phase here since we throw out the result of the coercion
|
||||
let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
|
||||
self.probe(|_| coerce.coerce(source, target)).is_ok()
|
||||
}
|
||||
|
||||
/// Same as `try_coerce()`, but without side-effects and attempts to select
|
||||
/// all predicates created by the coercion. This is useful for e.g. checking
|
||||
/// that associated types are correct.
|
||||
pub fn can_coerce_and_satisfy_predicates(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
|
||||
let source = self.resolve_vars_with_obligations(expr_ty);
|
||||
debug!("coercion::can_with_predicates({:?} -> {:?})", source, target);
|
||||
|
||||
|
@ -373,7 +373,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let box_found = self.tcx.mk_box(found);
|
||||
let pin_box_found = self.tcx.mk_lang_item(box_found, LangItem::Pin).unwrap();
|
||||
let pin_found = self.tcx.mk_lang_item(found, LangItem::Pin).unwrap();
|
||||
if self.can_coerce_and_satisfy_predicates(pin_box_found, expected) {
|
||||
if self.can_coerce(pin_box_found, expected) {
|
||||
debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected);
|
||||
match found.kind() {
|
||||
ty::Adt(def, _) if def.is_box() => {
|
||||
@ -391,7 +391,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
true
|
||||
} else if self.can_coerce_and_satisfy_predicates(pin_found, expected) {
|
||||
} else if self.can_coerce(pin_found, expected) {
|
||||
match found.kind() {
|
||||
ty::Adt(def, _) if def.is_box() => {
|
||||
err.help("use `Box::pin`");
|
||||
|
@ -2,10 +2,8 @@ error[E0308]: mismatched types
|
||||
--> $DIR/cross-borrow-trait.rs:10:26
|
||||
|
|
||||
LL | let _y: &dyn Trait = x;
|
||||
| ---------- ^
|
||||
| | |
|
||||
| | expected `&dyn Trait`, found struct `Box`
|
||||
| | help: consider borrowing here: `&x`
|
||||
| ---------- ^ expected `&dyn Trait`, found struct `Box`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected reference `&dyn Trait`
|
||||
|
@ -13,10 +13,8 @@ error[E0308]: mismatched types
|
||||
--> $DIR/dst-bad-coercions.rs:15:21
|
||||
|
|
||||
LL | let y: &dyn T = x;
|
||||
| ------ ^
|
||||
| | |
|
||||
| | expected `&dyn T`, found *-ptr
|
||||
| | help: consider borrowing here: `&x`
|
||||
| ------ ^ expected `&dyn T`, found *-ptr
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected reference `&dyn T`
|
||||
@ -37,10 +35,8 @@ error[E0308]: mismatched types
|
||||
--> $DIR/dst-bad-coercions.rs:20:21
|
||||
|
|
||||
LL | let y: &dyn T = x;
|
||||
| ------ ^
|
||||
| | |
|
||||
| | expected `&dyn T`, found *-ptr
|
||||
| | help: consider borrowing here: `&x`
|
||||
| ------ ^ expected `&dyn T`, found *-ptr
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected reference `&dyn T`
|
||||
|
Loading…
x
Reference in New Issue
Block a user