]> git.lizzy.rs Git - rust.git/commitdiff
no unnormalized types for implied bounds
authorlcnr <rust@lcnr.de>
Thu, 25 Aug 2022 09:12:04 +0000 (11:12 +0200)
committerlcnr <rust@lcnr.de>
Thu, 25 Aug 2022 09:12:04 +0000 (11:12 +0200)
compiler/rustc_trait_selection/src/traits/engine.rs
src/test/ui/implied-bounds/impl-header-unnormalized-types.rs [new file with mode: 0644]
src/test/ui/implied-bounds/impl-header-unnormalized-types.stderr [new file with mode: 0644]

index 136b94321459ee062840443e9534b30dc101f835..72533a42d8078dce6949d9d67850eccab50576fa 100644 (file)
@@ -124,7 +124,18 @@ pub fn assumed_wf_types(
         let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
         let cause = ObligationCause::misc(span, hir_id);
         for ty in assumed_wf_types {
-            implied_bounds.insert(ty);
+            // FIXME(@lcnr): rustc currently does not check wf for types
+            // pre-normalization, meaning that implied bounds are sometimes
+            // incorrect. See #100910 for more details.
+            //
+            // Not adding the unnormalized types here mostly fixes that, except
+            // that there are projections which are still ambiguous in the item definition
+            // but do normalize successfully when using the item, see #98543.
+            //
+            // Anyways, I will hopefully soon change implied bounds to make all of this
+            // sound and then uncomment this line again.
+
+            // implied_bounds.insert(ty);
             let normalized = self.normalize(cause.clone(), param_env, ty);
             implied_bounds.insert(normalized);
         }
diff --git a/src/test/ui/implied-bounds/impl-header-unnormalized-types.rs b/src/test/ui/implied-bounds/impl-header-unnormalized-types.rs
new file mode 100644 (file)
index 0000000..d84539f
--- /dev/null
@@ -0,0 +1,28 @@
+struct Foo<T>(T);
+
+trait GoodBye {
+    type Forget;
+}
+impl<T> GoodBye for T {
+    type Forget = ();
+}
+
+trait NeedsWf<'a, 'b> {
+    type Assoc;
+}
+
+impl<'a, 'b> NeedsWf<'a, 'b> for Foo<<&'a &'b () as GoodBye>::Forget> {
+    type Assoc = &'a &'b ();
+    //~^ ERROR in type `&'a &'b ()`, reference has a longer lifetime than the data it references
+}
+
+fn needs_wf<'a, 'b, T: NeedsWf<'a, 'b>>() {}
+
+fn foo<'a: 'a, 'b: 'b>(_: &'b String) {
+    needs_wf::<'a, 'b, Foo<()>>();
+}
+
+fn main() {
+    let x = String::from("hello");
+    foo::<'static, '_>(&x);
+}
diff --git a/src/test/ui/implied-bounds/impl-header-unnormalized-types.stderr b/src/test/ui/implied-bounds/impl-header-unnormalized-types.stderr
new file mode 100644 (file)
index 0000000..88abd5f
--- /dev/null
@@ -0,0 +1,20 @@
+error[E0491]: in type `&'a &'b ()`, reference has a longer lifetime than the data it references
+  --> $DIR/impl-header-unnormalized-types.rs:15:18
+   |
+LL |     type Assoc = &'a &'b ();
+   |                  ^^^^^^^^^^
+   |
+note: the pointer is valid for the lifetime `'a` as defined here
+  --> $DIR/impl-header-unnormalized-types.rs:14:6
+   |
+LL | impl<'a, 'b> NeedsWf<'a, 'b> for Foo<<&'a &'b () as GoodBye>::Forget> {
+   |      ^^
+note: but the referenced data is only valid for the lifetime `'b` as defined here
+  --> $DIR/impl-header-unnormalized-types.rs:14:10
+   |
+LL | impl<'a, 'b> NeedsWf<'a, 'b> for Foo<<&'a &'b () as GoodBye>::Forget> {
+   |          ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.