about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2023-11-25 13:11:38 +0000
committerDeadbeef <ent3rm4n@gmail.com>2023-11-25 13:11:38 +0000
commitd5ebdfc2c55e6ec3c6e50775d7c30d4c29d78651 (patch)
treecca53d910ffd33562d9e38974805f566cb9bd24f
parentfad6bb80fa89100e839ea7cbb4e9999188c0ac0d (diff)
downloadrust-d5ebdfc2c55e6ec3c6e50775d7c30d4c29d78651.tar.gz
rust-d5ebdfc2c55e6ec3c6e50775d7c30d4c29d78651.zip
effects: Run `enforce_context_effects` for all method calls
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/place_op.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr18
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs4
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr75
11 files changed, 94 insertions, 46 deletions
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index d40ac59baa4..fa5833a78a2 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -845,7 +845,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             expected,
         );
 
-        self.write_method_call(call_expr.hir_id, method_callee);
+        self.write_method_call(call_expr.hir_id, call_expr.span, method_callee);
         output_type
     }
 }
@@ -895,7 +895,7 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> {
                 adjustments.extend(autoref);
                 fcx.apply_adjustments(self.callee_expr, adjustments);
 
-                fcx.write_method_call(self.call_expr.hir_id, method_callee);
+                fcx.write_method_call(self.call_expr.hir_id, self.call_expr.span, method_callee);
             }
             None => {
                 // This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once`
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index fdf1152a235..b0d32c5a199 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1313,9 +1313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Ok(method) => {
                 // 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.
-
-                self.enforce_context_effects(expr.hir_id, expr.span, method.def_id, method.args);
-                self.write_method_call(expr.hir_id, method);
+                self.write_method_call(expr.hir_id, expr.span, method);
                 Ok(method)
             }
             Err(error) => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 9bacebb1039..569ed8dfcaf 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -159,7 +159,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
+    pub fn write_method_call(&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_args(hir_id, method.args);
     }
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 66a0f4ed9de..8709cef5947 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -442,9 +442,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 {
     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) {
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index f40406c6726..c7b785fbcd0 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -291,7 +291,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             .push(autoref);
                     }
                 }
-                self.write_method_call(expr.hir_id, method);
+                self.write_method_call(expr.hir_id, expr.span, method);
 
                 method.sig.output()
             }
@@ -781,7 +781,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         assert!(op.is_by_value());
         match self.lookup_op_method(operand_ty, None, Op::Unary(op, ex.span), expected) {
             Ok(method) => {
-                self.write_method_call(ex.hir_id, method);
+                self.write_method_call(ex.hir_id, ex.span, method);
                 method.sig.output()
             }
             Err(errors) => {
diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs
index f8ca3a4f3d7..12ebde25c33 100644
--- a/compiler/rustc_hir_typeck/src/place_op.rs
+++ b/compiler/rustc_hir_typeck/src/place_op.rs
@@ -38,7 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             span_bug!(expr.span, "input to deref is not a ref?");
         }
         let ty = self.make_overloaded_place_return_type(method).ty;
-        self.write_method_call(expr.hir_id, method);
+        self.write_method_call(expr.hir_id, expr.span, method);
         Some(ty)
     }
 
@@ -179,7 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
                 self.apply_adjustments(base_expr, adjustments);
 
-                self.write_method_call(expr.hir_id, method);
+                self.write_method_call(expr.hir_id, expr.span, method);
 
                 return Some((input_ty, self.make_overloaded_place_return_type(method).ty));
             }
@@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             None => return,
         };
         debug!("convert_place_op_to_mutable: method={:?}", method);
-        self.write_method_call(expr.hir_id, method);
+        self.write_method_call(expr.hir_id, expr.span, method);
 
         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?");
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 440767927d7..c4bf2f23899 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -263,13 +263,13 @@ impl<'tcx> ConstToPat<'tcx> {
         // (If there isn't, then we can safely issue a hard
         // error, because that's never worked, due to compiler
         // using `PartialEq::eq` in this scenario in the past.)
-        let partial_eq_trait_id =
-            self.tcx().require_lang_item(hir::LangItem::PartialEq, Some(self.span));
+        let tcx = self.tcx();
+        let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
         let partial_eq_obligation = Obligation::new(
-            self.tcx(),
+            tcx,
             ObligationCause::dummy(),
             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
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
index eada4ceafe9..b9331caaf8e 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs
@@ -1,7 +1,4 @@
-// check-pass
-// known-bug: #110395
-
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, effects)]
 
 struct S;
 
@@ -24,6 +21,7 @@ const fn equals_self<T: ~const Foo>(t: &T) -> bool {
 // it not using the impl.
 
 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() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
new file mode 100644
index 00000000000..4fe296d4d3f
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr
@@ -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`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs
index c38b4b3f1a2..67da5f9533c 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs
@@ -21,7 +21,7 @@ trait Add<Rhs = Self> {
     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 {
     type Output = i32;
     fn add(self, rhs: i32) -> i32 {
@@ -336,7 +336,7 @@ fn from_str(s: &str) -> Result<bool, ()> {
 }
 
 #[lang = "eq"]
-#[const_trait]
+// FIXME #[const_trait]
 trait PartialEq<Rhs: ?Sized = Self> {
     fn eq(&self, other: &Rhs) -> bool;
     fn ne(&self, other: &Rhs) -> bool {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr
index 02429374218..19e6f6bffc6 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr
@@ -1,32 +1,61 @@
-error[E0369]: cannot add `i32` to `i32`
-  --> $DIR/minicore.rs:33:20
+warning: to use a constant of type `&str` in a pattern, the type must implement `PartialEq`
+  --> $DIR/minicore.rs:332:9
    |
-LL |     let x = 42_i32 + 43_i32;
-   |             ------ ^ ------ i32
-   |             |
-   |             i32
+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
+
+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>
 
-error[E0369]: cannot add `i32` to `i32`
-  --> $DIR/minicore.rs:37:20
+error[E0493]: destructor of `Self` cannot be evaluated at compile-time
+  --> $DIR/minicore.rs:494:9
    |
-LL |     let x = 42_i32 + 43_i32;
-   |             ------ ^ ------ i32
-   |             |
-   |             i32
+LL |         *self = source.clone()
+   |         ^^^^^
+   |         |
+   |         the destructor for this type cannot be evaluated in constant functions
+   |         value is dropped here
 
-error[E0600]: cannot apply unary operator `!` to type `bool`
-  --> $DIR/minicore.rs:343:9
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/minicore.rs:504:35
    |
-LL |         !self.eq(other)
-   |         ^^^^^^^^^^^^^^^ cannot apply unary operator `!`
+LL | const fn drop<T: ~const Destruct>(_: T) {}
+   |                                   ^      - value is dropped here
+   |                                   |
+   |                                   the destructor for this type cannot be evaluated in constant functions
 
-error[E0600]: cannot apply unary operator `!` to type `bool`
-  --> $DIR/minicore.rs:365:9
+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),
+   |         ^^^^^^
    |
-LL |         !self
-   |         ^^^^^ cannot apply unary operator `!`
+   = 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
 
-error: aborting due to 4 previous errors
+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`.