Auto merge of #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`
This commit is contained in:
commit
e06c94d6cb
@ -845,7 +845,7 @@ fn confirm_overloaded_call(
|
|||||||
expected,
|
expected,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.write_method_call(call_expr.hir_id, method_callee);
|
self.write_method_call_and_enforce_effects(call_expr.hir_id, call_expr.span, method_callee);
|
||||||
output_type
|
output_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -895,7 +895,11 @@ pub fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) {
|
|||||||
adjustments.extend(autoref);
|
adjustments.extend(autoref);
|
||||||
fcx.apply_adjustments(self.callee_expr, adjustments);
|
fcx.apply_adjustments(self.callee_expr, adjustments);
|
||||||
|
|
||||||
fcx.write_method_call(self.call_expr.hir_id, method_callee);
|
fcx.write_method_call_and_enforce_effects(
|
||||||
|
self.call_expr.hir_id,
|
||||||
|
self.call_expr.span,
|
||||||
|
method_callee,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once`
|
// This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once`
|
||||||
|
@ -1315,9 +1315,7 @@ fn check_method_call(
|
|||||||
Ok(method) => {
|
Ok(method) => {
|
||||||
// We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
|
// We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
|
||||||
// trigger this codepath causing `structurally_resolve_type` to emit an error.
|
// trigger this codepath causing `structurally_resolve_type` to emit an error.
|
||||||
|
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
|
||||||
self.enforce_context_effects(expr.hir_id, expr.span, method.def_id, method.args);
|
|
||||||
self.write_method_call(expr.hir_id, method);
|
|
||||||
Ok(method)
|
Ok(method)
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
|
@ -159,7 +159,13 @@ pub(in super::super) fn write_resolution(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
|
pub fn write_method_call_and_enforce_effects(
|
||||||
|
&self,
|
||||||
|
hir_id: hir::HirId,
|
||||||
|
span: Span,
|
||||||
|
method: MethodCallee<'tcx>,
|
||||||
|
) {
|
||||||
|
self.enforce_context_effects(hir_id, span, method.def_id, method.args);
|
||||||
self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
|
self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
|
||||||
self.write_args(hir_id, method.args);
|
self.write_args(hir_id, method.args);
|
||||||
}
|
}
|
||||||
|
@ -438,9 +438,13 @@ fn fatally_break_rust(tcx: TyCtxt<'_>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `expected` here is the expected number of explicit generic arguments on the trait.
|
||||||
fn has_expected_num_generic_args(tcx: TyCtxt<'_>, trait_did: DefId, expected: usize) -> bool {
|
fn has_expected_num_generic_args(tcx: TyCtxt<'_>, trait_did: DefId, expected: usize) -> bool {
|
||||||
let generics = tcx.generics_of(trait_did);
|
let generics = tcx.generics_of(trait_did);
|
||||||
generics.count() == expected + if generics.has_self { 1 } else { 0 }
|
generics.count()
|
||||||
|
== expected
|
||||||
|
+ if generics.has_self { 1 } else { 0 }
|
||||||
|
+ if generics.host_effect_index.is_some() { 1 } else { 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
|
@ -291,7 +291,7 @@ fn check_overloaded_binop(
|
|||||||
.push(autoref);
|
.push(autoref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.write_method_call(expr.hir_id, method);
|
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
|
||||||
|
|
||||||
method.sig.output()
|
method.sig.output()
|
||||||
}
|
}
|
||||||
@ -781,7 +781,7 @@ pub fn check_user_unop(
|
|||||||
assert!(op.is_by_value());
|
assert!(op.is_by_value());
|
||||||
match self.lookup_op_method(operand_ty, None, Op::Unary(op, ex.span), expected) {
|
match self.lookup_op_method(operand_ty, None, Op::Unary(op, ex.span), expected) {
|
||||||
Ok(method) => {
|
Ok(method) => {
|
||||||
self.write_method_call(ex.hir_id, method);
|
self.write_method_call_and_enforce_effects(ex.hir_id, ex.span, method);
|
||||||
method.sig.output()
|
method.sig.output()
|
||||||
}
|
}
|
||||||
Err(errors) => {
|
Err(errors) => {
|
||||||
|
@ -38,7 +38,7 @@ pub(super) fn lookup_derefing(
|
|||||||
span_bug!(expr.span, "input to deref is not a ref?");
|
span_bug!(expr.span, "input to deref is not a ref?");
|
||||||
}
|
}
|
||||||
let ty = self.make_overloaded_place_return_type(method).ty;
|
let ty = self.make_overloaded_place_return_type(method).ty;
|
||||||
self.write_method_call(expr.hir_id, method);
|
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
|
||||||
Some(ty)
|
Some(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ fn try_index_step(
|
|||||||
}
|
}
|
||||||
self.apply_adjustments(base_expr, adjustments);
|
self.apply_adjustments(base_expr, adjustments);
|
||||||
|
|
||||||
self.write_method_call(expr.hir_id, method);
|
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
|
||||||
|
|
||||||
return Some((input_ty, self.make_overloaded_place_return_type(method).ty));
|
return Some((input_ty, self.make_overloaded_place_return_type(method).ty));
|
||||||
}
|
}
|
||||||
@ -404,7 +404,7 @@ fn convert_place_op_to_mutable(
|
|||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
debug!("convert_place_op_to_mutable: method={:?}", method);
|
debug!("convert_place_op_to_mutable: method={:?}", method);
|
||||||
self.write_method_call(expr.hir_id, method);
|
self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method);
|
||||||
|
|
||||||
let ty::Ref(region, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind() else {
|
let ty::Ref(region, _, hir::Mutability::Mut) = method.sig.inputs()[0].kind() else {
|
||||||
span_bug!(expr.span, "input to mutable place op is not a mut ref?");
|
span_bug!(expr.span, "input to mutable place op is not a mut ref?");
|
||||||
|
@ -263,13 +263,13 @@ fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
|
|||||||
// (If there isn't, then we can safely issue a hard
|
// (If there isn't, then we can safely issue a hard
|
||||||
// error, because that's never worked, due to compiler
|
// error, because that's never worked, due to compiler
|
||||||
// using `PartialEq::eq` in this scenario in the past.)
|
// using `PartialEq::eq` in this scenario in the past.)
|
||||||
let partial_eq_trait_id =
|
let tcx = self.tcx();
|
||||||
self.tcx().require_lang_item(hir::LangItem::PartialEq, Some(self.span));
|
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
|
||||||
let partial_eq_obligation = Obligation::new(
|
let partial_eq_obligation = Obligation::new(
|
||||||
self.tcx(),
|
tcx,
|
||||||
ObligationCause::dummy(),
|
ObligationCause::dummy(),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ty::TraitRef::new(self.tcx(), partial_eq_trait_id, [ty, ty]),
|
ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]),
|
||||||
);
|
);
|
||||||
|
|
||||||
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get
|
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
// check-pass
|
#![feature(const_trait_impl, effects)]
|
||||||
// known-bug: #110395
|
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
@ -24,6 +21,7 @@ const fn equals_self<T: ~const Foo>(t: &T) -> bool {
|
|||||||
// it not using the impl.
|
// it not using the impl.
|
||||||
|
|
||||||
pub const EQ: bool = equals_self(&S);
|
pub const EQ: bool = equals_self(&S);
|
||||||
// FIXME(effects) ~^ ERROR
|
//~^ ERROR
|
||||||
|
// FIXME(effects) the diagnostics here isn't ideal, we shouldn't get `<false>`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
error[E0277]: the trait bound `S: ~const Foo<false>` is not satisfied
|
||||||
|
--> $DIR/call-generic-method-nonconst.rs:23:34
|
||||||
|
|
|
||||||
|
LL | pub const EQ: bool = equals_self(&S);
|
||||||
|
| ----------- ^^ the trait `Foo<false>` is not implemented for `S`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= help: the trait `Foo` is implemented for `S`
|
||||||
|
note: required by a bound in `equals_self`
|
||||||
|
--> $DIR/call-generic-method-nonconst.rs:16:25
|
||||||
|
|
|
||||||
|
LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
|
||||||
|
| ^^^^^^^^^^ required by this bound in `equals_self`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
@ -21,7 +21,7 @@ trait Add<Rhs = Self> {
|
|||||||
fn add(self, rhs: Rhs) -> Self::Output;
|
fn add(self, rhs: Rhs) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME we shouldn't need to have to specify `Rhs`.
|
// FIXME(effects) we shouldn't need to have to specify `Rhs`.
|
||||||
impl const Add<i32> for i32 {
|
impl const Add<i32> for i32 {
|
||||||
type Output = i32;
|
type Output = i32;
|
||||||
fn add(self, rhs: i32) -> i32 {
|
fn add(self, rhs: i32) -> i32 {
|
||||||
@ -336,7 +336,7 @@ fn from_str(s: &str) -> Result<bool, ()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eq"]
|
#[lang = "eq"]
|
||||||
#[const_trait]
|
// FIXME #[const_trait]
|
||||||
trait PartialEq<Rhs: ?Sized = Self> {
|
trait PartialEq<Rhs: ?Sized = Self> {
|
||||||
fn eq(&self, other: &Rhs) -> bool;
|
fn eq(&self, other: &Rhs) -> bool;
|
||||||
fn ne(&self, other: &Rhs) -> bool {
|
fn ne(&self, other: &Rhs) -> bool {
|
||||||
|
@ -1,32 +1,61 @@
|
|||||||
error[E0369]: cannot add `i32` to `i32`
|
warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq`
|
||||||
--> $DIR/minicore.rs:33:20
|
--> $DIR/minicore.rs:332:9
|
||||||
|
|
|
|
||||||
LL | let x = 42_i32 + 43_i32;
|
LL | "true" => Ok(true),
|
||||||
| ------ ^ ------ i32
|
| ^^^^^^
|
||||||
| |
|
|
||||||
| i32
|
|
||||||
|
|
||||||
error[E0369]: cannot add `i32` to `i32`
|
|
||||||
--> $DIR/minicore.rs:37:20
|
|
||||||
|
|
|
|
||||||
LL | let x = 42_i32 + 43_i32;
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
| ------ ^ ------ i32
|
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
|
||||||
| |
|
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
|
||||||
| i32
|
|
||||||
|
|
||||||
error[E0600]: cannot apply unary operator `!` to type `bool`
|
warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq`
|
||||||
--> $DIR/minicore.rs:343:9
|
--> $DIR/minicore.rs:333:9
|
||||||
|
|
|
|
||||||
LL | !self.eq(other)
|
LL | "false" => Ok(false),
|
||||||
| ^^^^^^^^^^^^^^^ cannot apply unary operator `!`
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0600]: cannot apply unary operator `!` to type `bool`
|
|
||||||
--> $DIR/minicore.rs:365:9
|
|
||||||
|
|
|
|
||||||
LL | !self
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
| ^^^^^ cannot apply unary operator `!`
|
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error[E0493]: destructor of `Self` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/minicore.rs:494:9
|
||||||
|
|
|
||||||
|
LL | *self = source.clone()
|
||||||
|
| ^^^^^
|
||||||
|
| |
|
||||||
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
| value is dropped here
|
||||||
|
|
||||||
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/minicore.rs:504:35
|
||||||
|
|
|
||||||
|
LL | const fn drop<T: ~const Destruct>(_: T) {}
|
||||||
|
| ^ - value is dropped here
|
||||||
|
| |
|
||||||
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors; 2 warnings emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
Future incompatibility report: Future breakage diagnostic:
|
||||||
|
warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq`
|
||||||
|
--> $DIR/minicore.rs:332:9
|
||||||
|
|
|
||||||
|
LL | "true" => Ok(true),
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
|
||||||
|
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
|
||||||
|
|
||||||
|
Future breakage diagnostic:
|
||||||
|
warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq`
|
||||||
|
--> $DIR/minicore.rs:333:9
|
||||||
|
|
|
||||||
|
LL | "false" => Ok(false),
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
|
||||||
|
= note: `#[warn(const_patterns_without_partial_eq)]` on by default
|
||||||
|
|
||||||
Some errors have detailed explanations: E0369, E0600.
|
|
||||||
For more information about an error, try `rustc --explain E0369`.
|
|
||||||
|
Loading…
Reference in New Issue
Block a user