When type-checking binops, LHS of assign-op like += is invariant.
Therefore we cannot coerce it to a supertype the same way that we can the LHS of `+`. Addresses issue 52126.
This commit is contained in:
parent
4260c8b1e4
commit
c83602a702
1 changed files with 18 additions and 11 deletions
|
|
@ -165,18 +165,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
op,
|
||||
is_assign);
|
||||
|
||||
let lhs_needs = match is_assign {
|
||||
IsAssign::Yes => Needs::MutPlace,
|
||||
IsAssign::No => Needs::None
|
||||
let lhs_ty = match is_assign {
|
||||
IsAssign::No => {
|
||||
// Find a suitable supertype of the LHS expression's type, by coercing to
|
||||
// a type variable, to pass as the `Self` to the trait, avoiding invariant
|
||||
// trait matching creating lifetime constraints that are too strict.
|
||||
// E.g. adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
|
||||
// in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
|
||||
let lhs_ty = self.check_expr_with_needs(lhs_expr, Needs::None);
|
||||
let fresh_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(lhs_expr.span));
|
||||
self.demand_coerce(lhs_expr, lhs_ty, fresh_var, AllowTwoPhase::No)
|
||||
}
|
||||
IsAssign::Yes => {
|
||||
// rust-lang/rust#52126: We have to use strict
|
||||
// equivalence on the LHS of an assign-op like `+=`;
|
||||
// overwritten or mutably-borrowed places cannot be
|
||||
// coerced to a supertype.
|
||||
self.check_expr_with_needs(lhs_expr, Needs::MutPlace)
|
||||
}
|
||||
};
|
||||
// Find a suitable supertype of the LHS expression's type, by coercing to
|
||||
// a type variable, to pass as the `Self` to the trait, avoiding invariant
|
||||
// trait matching creating lifetime constraints that are too strict.
|
||||
// E.g. adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
|
||||
// in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
|
||||
let lhs_ty = self.check_expr_with_needs(lhs_expr, lhs_needs);
|
||||
let fresh_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(lhs_expr.span));
|
||||
let lhs_ty = self.demand_coerce(lhs_expr, lhs_ty, fresh_var, AllowTwoPhase::No);
|
||||
let lhs_ty = self.resolve_type_vars_with_obligations(lhs_ty);
|
||||
|
||||
// NB: As we have not yet type-checked the RHS, we don't have the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue