Skip to content

Commit e06c94d

Browse files
committed
Auto merge of rust-lang#118282 - fee1-dead-contrib:enforce-more, r=compiler-errors
effects: Run `enforce_context_effects` for all method calls So that we also perform checks when overloaded `PartialEq`s are called. r? `@compiler-errors`
2 parents c2ec908 + dd3437b commit e06c94d

File tree

11 files changed

+103
-46
lines changed

11 files changed

+103
-46
lines changed

compiler/rustc_hir_typeck/src/callee.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
845845
expected,
846846
);
847847

848-
self.write_method_call(call_expr.hir_id, method_callee);
848+
self.write_method_call_and_enforce_effects(call_expr.hir_id, call_expr.span, method_callee);
849849
output_type
850850
}
851851
}
@@ -895,7 +895,11 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> {
895895
adjustments.extend(autoref);
896896
fcx.apply_adjustments(self.callee_expr, adjustments);
897897

898-
fcx.write_method_call(self.call_expr.hir_id, method_callee);
898+
fcx.write_method_call_and_enforce_effects(
899+
self.call_expr.hir_id,
900+
self.call_expr.span,
901+
method_callee,
902+
);
899903
}
900904
None => {
901905
// This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once`

compiler/rustc_hir_typeck/src/expr.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1315,9 +1315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13151315
Ok(method) => {
13161316
// We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
13171317
// trigger this codepath causing `structurally_resolve_type` to emit an error.
1318-
1319-
self.enforce_context_effects(expr.hir_id, expr.span, method.def_id, method.args);
1320-
self.write_method_call(expr.hir_id, method);
1318+
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
13211319
Ok(method)
13221320
}
13231321
Err(error) => {

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
159159
}
160160

161161
#[instrument(level = "debug", skip(self))]
162-
pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
162+
pub fn write_method_call_and_enforce_effects(
163+
&self,
164+
hir_id: hir::HirId,
165+
span: Span,
166+
method: MethodCallee<'tcx>,
167+
) {
168+
self.enforce_context_effects(hir_id, span, method.def_id, method.args);
163169
self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
164170
self.write_args(hir_id, method.args);
165171
}

compiler/rustc_hir_typeck/src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,13 @@ fn fatally_break_rust(tcx: TyCtxt<'_>) {
438438
}
439439
}
440440

441+
/// `expected` here is the expected number of explicit generic arguments on the trait.
441442
fn has_expected_num_generic_args(tcx: TyCtxt<'_>, trait_did: DefId, expected: usize) -> bool {
442443
let generics = tcx.generics_of(trait_did);
443-
generics.count() == expected + if generics.has_self { 1 } else { 0 }
444+
generics.count()
445+
== expected
446+
+ if generics.has_self { 1 } else { 0 }
447+
+ if generics.host_effect_index.is_some() { 1 } else { 0 }
444448
}
445449

446450
pub fn provide(providers: &mut Providers) {

compiler/rustc_hir_typeck/src/op.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
291291
.push(autoref);
292292
}
293293
}
294-
self.write_method_call(expr.hir_id, method);
294+
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
295295

296296
method.sig.output()
297297
}
@@ -781,7 +781,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
781781
assert!(op.is_by_value());
782782
match self.lookup_op_method(operand_ty, None, Op::Unary(op, ex.span), expected) {
783783
Ok(method) => {
784-
self.write_method_call(ex.hir_id, method);
784+
self.write_method_call_and_enforce_effects(ex.hir_id, ex.span, method);
785785
method.sig.output()
786786
}
787787
Err(errors) => {

compiler/rustc_hir_typeck/src/place_op.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3838
span_bug!(expr.span, "input to deref is not a ref?");
3939
}
4040
let ty = self.make_overloaded_place_return_type(method).ty;
41-
self.write_method_call(expr.hir_id, method);
41+
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
4242
Some(ty)
4343
}
4444

@@ -179,7 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
179179
}
180180
self.apply_adjustments(base_expr, adjustments);
181181

182-
self.write_method_call(expr.hir_id, method);
182+
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
183183

184184
return Some((input_ty, self.make_overloaded_place_return_type(method).ty));
185185
}
@@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
404404
None => return,
405405
};
406406
debug!("convert_place_op_to_mutable: method={:?}", method);
407-
self.write_method_call(expr.hir_id, method);
407+
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
408408

409409
let ty::Ref(region, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind() else {
410410
span_bug!(expr.span, "input to mutable place op is not a mut ref?");

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,13 @@ impl<'tcx> ConstToPat<'tcx> {
263263
// (If there isn't, then we can safely issue a hard
264264
// error, because that's never worked, due to compiler
265265
// using `PartialEq::eq` in this scenario in the past.)
266-
let partial_eq_trait_id =
267-
self.tcx().require_lang_item(hir::LangItem::PartialEq, Some(self.span));
266+
let tcx = self.tcx();
267+
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
268268
let partial_eq_obligation = Obligation::new(
269-
self.tcx(),
269+
tcx,
270270
ObligationCause::dummy(),
271271
self.param_env,
272-
ty::TraitRef::new(self.tcx(), partial_eq_trait_id, [ty, ty]),
272+
ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]),
273273
);
274274

275275
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get

tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
// check-pass
2-
// known-bug: #110395
3-
4-
#![feature(const_trait_impl)]
1+
#![feature(const_trait_impl, effects)]
52

63
struct S;
74

@@ -24,6 +21,7 @@ const fn equals_self<T: ~const Foo>(t: &T) -> bool {
2421
// it not using the impl.
2522

2623
pub const EQ: bool = equals_self(&S);
27-
// FIXME(effects) ~^ ERROR
24+
//~^ ERROR
25+
// FIXME(effects) the diagnostics here isn't ideal, we shouldn't get `<false>`
2826

2927
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0277]: the trait bound `S: ~const Foo<false>` is not satisfied
2+
--> $DIR/call-generic-method-nonconst.rs:23:34
3+
|
4+
LL | pub const EQ: bool = equals_self(&S);
5+
| ----------- ^^ the trait `Foo<false>` is not implemented for `S`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `Foo` is implemented for `S`
10+
note: required by a bound in `equals_self`
11+
--> $DIR/call-generic-method-nonconst.rs:16:25
12+
|
13+
LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
14+
| ^^^^^^^^^^ required by this bound in `equals_self`
15+
16+
error: aborting due to 1 previous error
17+
18+
For more information about this error, try `rustc --explain E0277`.

tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ trait Add<Rhs = Self> {
2121
fn add(self, rhs: Rhs) -> Self::Output;
2222
}
2323

24-
// FIXME we shouldn't need to have to specify `Rhs`.
24+
// FIXME(effects) we shouldn't need to have to specify `Rhs`.
2525
impl const Add<i32> for i32 {
2626
type Output = i32;
2727
fn add(self, rhs: i32) -> i32 {
@@ -336,7 +336,7 @@ fn from_str(s: &str) -> Result<bool, ()> {
336336
}
337337

338338
#[lang = "eq"]
339-
#[const_trait]
339+
// FIXME #[const_trait]
340340
trait PartialEq<Rhs: ?Sized = Self> {
341341
fn eq(&self, other: &Rhs) -> bool;
342342
fn ne(&self, other: &Rhs) -> bool {

tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr

+52-23
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,61 @@
1-
error[E0369]: cannot add `i32` to `i32`
2-
--> $DIR/minicore.rs:33:20
1+
warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq`
2+
--> $DIR/minicore.rs:332:9
33
|
4-
LL | let x = 42_i32 + 43_i32;
5-
| ------ ^ ------ i32
6-
| |
7-
| i32
4+
LL | "true" => Ok(true),
5+
| ^^^^^^
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
9+
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
10+
11+
warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq`
12+
--> $DIR/minicore.rs:333:9
13+
|
14+
LL | "false" => Ok(false),
15+
| ^^^^^^^
16+
|
17+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
18+
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
819

9-
error[E0369]: cannot add `i32` to `i32`
10-
--> $DIR/minicore.rs:37:20
20+
error[E0493]: destructor of `Self` cannot be evaluated at compile-time
21+
--> $DIR/minicore.rs:494:9
1122
|
12-
LL | let x = 42_i32 + 43_i32;
13-
| ------ ^ ------ i32
14-
| |
15-
| i32
23+
LL | *self = source.clone()
24+
| ^^^^^
25+
| |
26+
| the destructor for this type cannot be evaluated in constant functions
27+
| value is dropped here
1628

17-
error[E0600]: cannot apply unary operator `!` to type `bool`
18-
--> $DIR/minicore.rs:343:9
29+
error[E0493]: destructor of `T` cannot be evaluated at compile-time
30+
--> $DIR/minicore.rs:504:35
1931
|
20-
LL | !self.eq(other)
21-
| ^^^^^^^^^^^^^^^ cannot apply unary operator `!`
32+
LL | const fn drop<T: ~const Destruct>(_: T) {}
33+
| ^ - value is dropped here
34+
| |
35+
| the destructor for this type cannot be evaluated in constant functions
2236

23-
error[E0600]: cannot apply unary operator `!` to type `bool`
24-
--> $DIR/minicore.rs:365:9
37+
error: aborting due to 2 previous errors; 2 warnings emitted
38+
39+
For more information about this error, try `rustc --explain E0493`.
40+
Future incompatibility report: Future breakage diagnostic:
41+
warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq`
42+
--> $DIR/minicore.rs:332:9
43+
|
44+
LL | "true" => Ok(true),
45+
| ^^^^^^
2546
|
26-
LL | !self
27-
| ^^^^^ cannot apply unary operator `!`
47+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
48+
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
49+
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
2850

29-
error: aborting due to 4 previous errors
51+
Future breakage diagnostic:
52+
warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq`
53+
--> $DIR/minicore.rs:333:9
54+
|
55+
LL | "false" => Ok(false),
56+
| ^^^^^^^
57+
|
58+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
59+
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
60+
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
3061

31-
Some errors have detailed explanations: E0369, E0600.
32-
For more information about an error, try `rustc --explain E0369`.

0 commit comments

Comments
 (0)