about summary refs log tree commit diff
path: root/compiler/rustc_data_structures/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-06-12 09:00:37 +0000
committerbors <bors@rust-lang.org>2024-06-12 09:00:37 +0000
commit02c7a5921e3de5c2b3ecb2e0082c1dafce0729a1 (patch)
tree6d0af7846e301f106565b6b497bbc55a201ea73f /compiler/rustc_data_structures/src
parentbdb1b7f5d9715cc96cb437134eff93fa229defd1 (diff)
parent85f2ecab576d3f02619b4d4976a6d7827c65ed4b (diff)
downloadrust-02c7a5921e3de5c2b3ecb2e0082c1dafce0729a1.tar.gz
rust-02c7a5921e3de5c2b3ecb2e0082c1dafce0729a1.zip
Auto merge of #113169 - oli-obk:tait_must_be_constrained_if_in_sig, r=lcnr
Tait must be constrained if in sig

r? `@compiler-errors`

kind of reverts https://github.com/rust-lang/rust/pull/62423, but that PR only removed cycles in cases that we want to forbid now anyway.

see https://rust-lang.zulipchat.com/#narrow/stream/315482-t-compiler.2Fetc.2Fopaque-types/topic/lcnr.20oli.20meeting/near/370712246 for related discussion and motivating example

a TAIT showing up in a signature doesn't just mean it can register a hidden type, but that it must.

This is the [design the types team decided upon](https://hackmd.io/QOsEaEJtQK-XDS_xN4UyQA#Proposal-preferred) for the following reasons

* avoids a hypothetical situation where getting smarter in trait solving could cause new cycle errors or new inference errors to show up, where today something is treated as opaque.
* avoids having the situation where a (minor?) change to a function body causes an error, because its TAIT usage suddenly isn't "opaque enough" anymore.
* avoids having to explain why in some cases you need to put a Tait into a tiny module together with its defining usages. Now you basically gotta always do this, the moment a Tait is in a signature that isn't in the defining scope.
* avoids false-cycle errors
* anything diverging from this pattern needs to either
    * move the TAIT declaration and defining function into their own helper sub module
    * use the attributes we'll provide in the future to explicitly opt in or out of being in the defining scope

fixes #117861

reverts #125362 cc `@Nilstrieb` `@joboet`
Diffstat (limited to 'compiler/rustc_data_structures/src')
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs27
1 files changed, 16 insertions, 11 deletions
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index d477b86da74..3883b0736db 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -146,8 +146,6 @@ pub enum ProcessResult<O, E> {
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 struct ObligationTreeId(usize);
 
-type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
-
 pub struct ObligationForest<O: ForestObligation> {
     /// The list of obligations. In between calls to [Self::process_obligations],
     /// this list only contains nodes in the `Pending` or `Waiting` state.
@@ -310,18 +308,25 @@ pub struct Error<O, E> {
     pub backtrace: Vec<O>,
 }
 
-impl<O: ForestObligation> ObligationForest<O> {
-    pub fn new() -> ObligationForest<O> {
-        ObligationForest {
-            nodes: vec![],
-            done_cache: Default::default(),
-            active_cache: Default::default(),
-            reused_node_vec: vec![],
-            obligation_tree_id_generator: (0..).map(ObligationTreeId),
-            error_cache: Default::default(),
+mod helper {
+    use super::*;
+    pub type ObligationTreeIdGenerator = impl Iterator<Item = ObligationTreeId>;
+    impl<O: ForestObligation> ObligationForest<O> {
+        pub fn new() -> ObligationForest<O> {
+            ObligationForest {
+                nodes: vec![],
+                done_cache: Default::default(),
+                active_cache: Default::default(),
+                reused_node_vec: vec![],
+                obligation_tree_id_generator: (0..).map(ObligationTreeId),
+                error_cache: Default::default(),
+            }
         }
     }
+}
+use helper::*;
 
+impl<O: ForestObligation> ObligationForest<O> {
     /// Returns the total number of nodes in the forest that have not
     /// yet been fully resolved.
     pub fn len(&self) -> usize {