Skip to content

Commit 50c1864

Browse files
committed
Auto merge of #40863 - eddyb:coerce-only-once, r=arielb1
Avoid type-checking addition and indexing twice. Fixes #40610 by moving the common `check_expr_coercable_to_type` call before the error reporting logic for binops and removing the one from `check_str_addition`. Fixes #40861 by removing an unnecessary `check_expr_coercable_to_type` call.
2 parents 44855a4 + edc7f9a commit 50c1864

File tree

4 files changed

+43
-11
lines changed

4 files changed

+43
-11
lines changed

src/librustc_typeck/check/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -3884,7 +3884,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
38843884
element_ty
38853885
}
38863886
None => {
3887-
self.check_expr_has_type(&idx, self.tcx.types.err);
38883887
let mut err = self.type_error_struct(
38893888
expr.span,
38903889
|actual| {

src/librustc_typeck/check/op.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
184184
// particularly for things like `String + &String`.
185185
let rhs_ty_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(rhs_expr.span));
186186

187-
let return_ty = match self.lookup_op_method(expr, lhs_ty, vec![rhs_ty_var],
188-
Symbol::intern(name), trait_def_id,
189-
lhs_expr) {
187+
let return_ty = self.lookup_op_method(expr, lhs_ty, vec![rhs_ty_var],
188+
Symbol::intern(name), trait_def_id,
189+
lhs_expr);
190+
191+
// see `NB` above
192+
let rhs_ty = self.check_expr_coercable_to_type(rhs_expr, rhs_ty_var);
193+
194+
let return_ty = match return_ty {
190195
Ok(return_ty) => return_ty,
191196
Err(()) => {
192197
// error types are considered "builtin"
@@ -209,7 +214,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
209214

210215
if let TypeVariants::TyRef(_, ref ty_mut) = lhs_ty.sty {
211216
if !self.infcx.type_moves_by_default(ty_mut.ty, lhs_expr.span) &&
212-
self.lookup_op_method(expr, ty_mut.ty, vec![rhs_ty_var],
217+
self.lookup_op_method(expr, ty_mut.ty, vec![rhs_ty],
213218
Symbol::intern(name), trait_def_id,
214219
lhs_expr).is_ok() {
215220
err.note(
@@ -240,7 +245,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
240245
if let Some(missing_trait) = missing_trait {
241246
if missing_trait == "std::ops::Add" &&
242247
self.check_str_addition(expr, lhs_expr, lhs_ty,
243-
rhs_expr, rhs_ty_var, &mut err) {
248+
rhs_expr, rhs_ty, &mut err) {
244249
// This has nothing here because it means we did string
245250
// concatenation (e.g. "Hello " + "World!"). This means
246251
// we don't want the note in the else clause to be emitted
@@ -257,9 +262,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
257262
}
258263
};
259264

260-
// see `NB` above
261-
self.check_expr_coercable_to_type(rhs_expr, rhs_ty_var);
262-
263265
(rhs_ty_var, return_ty)
264266
}
265267

@@ -268,12 +270,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
268270
lhs_expr: &'gcx hir::Expr,
269271
lhs_ty: Ty<'tcx>,
270272
rhs_expr: &'gcx hir::Expr,
271-
rhs_ty_var: Ty<'tcx>,
273+
rhs_ty: Ty<'tcx>,
272274
mut err: &mut errors::DiagnosticBuilder) -> bool {
273275
// If this function returns true it means a note was printed, so we don't need
274276
// to print the normal "implementation of `std::ops::Add` might be missing" note
275277
let mut is_string_addition = false;
276-
let rhs_ty = self.check_expr_coercable_to_type(rhs_expr, rhs_ty_var);
277278
if let TyRef(_, l_ty) = lhs_ty.sty {
278279
if let TyRef(_, r_ty) = rhs_ty.sty {
279280
if l_ty.ty.sty == TyStr && r_ty.ty.sty == TyStr {

src/test/compile-fail/issue-40610.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn f(_: &[f32]) {}
12+
13+
fn main() {
14+
() + f(&[1.0]);
15+
//~^ ERROR binary operation `+` cannot be applied to type `()`
16+
}

src/test/compile-fail/issue-40861.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn f(_: &[f32]) {}
12+
13+
fn main() {
14+
()[f(&[1.0])];
15+
//~^ ERROR cannot index a value of type `()`
16+
}

0 commit comments

Comments
 (0)