about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-20 20:17:13 -0400
committerMichael Goulet <michael@errs.io>2024-09-20 20:24:22 -0400
commita9a8f79f86a9251f29941bd79418e683692548e0 (patch)
tree2c28b8bb5eeee47f382abe17a70c42c08a35ae0e
parentda889684c80508036ff036db8c159ffdcf27648a (diff)
downloadrust-a9a8f79f86a9251f29941bd79418e683692548e0.tar.gz
rust-a9a8f79f86a9251f29941bd79418e683692548e0.zip
Normalize unevaluated consts in GCE
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs37
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-109141.rs3
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-109141.stderr33
-rw-r--r--tests/ui/const-generics/generic_const_exprs/opaque_type.rs1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/opaque_type.stderr14
5 files changed, 40 insertions, 48 deletions
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index c2555d2bb47..2fbbc3200e1 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -803,7 +803,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
         // We must deeply normalize in the new solver, since later lints
         // expect that types that show up in the typeck are fully
         // normalized.
-        let value = if self.should_normalize {
+        let mut value = if self.should_normalize {
             let body_id = tcx.hir().body_owner_def_id(self.body.id());
             let cause = ObligationCause::misc(self.span.to_span(tcx), body_id);
             let at = self.fcx.at(&cause, self.fcx.param_env);
@@ -818,12 +818,27 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
             value
         };
 
+        // Bail if there are any non-region infer.
         if value.has_non_region_infer() {
             let guar = self.report_error(value);
-            new_err(tcx, guar)
-        } else {
-            tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased)
+            value = new_err(tcx, guar);
+        }
+
+        // Erase the regions from the ty, since it's not really meaningful what
+        // these region values are; there's not a trivial correspondence between
+        // regions in the HIR and MIR, so when we turn the body into MIR, there's
+        // no reason to keep regions around. They will be repopulated during MIR
+        // borrowck, and specifically region constraints will be populated during
+        // MIR typeck which is run on the new body.
+        value = tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased);
+
+        // Normalize consts in writeback, because GCE doesn't normalize eagerly.
+        if tcx.features().generic_const_exprs {
+            value =
+                value.fold_with(&mut EagerlyNormalizeConsts { tcx, param_env: self.fcx.param_env });
         }
+
+        value
     }
 }
 
@@ -858,3 +873,17 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
         predicate
     }
 }
+
+struct EagerlyNormalizeConsts<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+}
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
+    fn cx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
+        self.tcx.try_normalize_erasing_regions(self.param_env, ct).unwrap_or(ct)
+    }
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.rs b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs
index c6dd981cced..5303b247173 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-109141.rs
+++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs
@@ -3,8 +3,7 @@
 
 impl EntriesBuffer {
     fn a(&self) -> impl Iterator {
-        self.0.iter_mut() //~ ERROR: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
-                          //~| ERROR captures lifetime that does not appear in bounds
+        self.0.iter_mut()
     }
 }
 
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr
index 24f3ed7cdf1..fcbd6904599 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `HashesEntryLEN` in this scope
-  --> $DIR/issue-109141.rs:11:32
+  --> $DIR/issue-109141.rs:10:32
    |
 LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>);
    |                                ^^^^^^^^^^^^^^ not found in this scope
@@ -9,33 +9,6 @@ help: you might be missing a const parameter
 LL | struct EntriesBuffer<const HashesEntryLEN: /* Type */>(Box<[[u8; HashesEntryLEN]; 5]>);
    |                     ++++++++++++++++++++++++++++++++++
 
-error[E0596]: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
-  --> $DIR/issue-109141.rs:6:9
-   |
-LL |         self.0.iter_mut()
-   |         ^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
-   |
-help: consider changing this to be a mutable reference
-   |
-LL |     fn a(&mut self) -> impl Iterator {
-   |          ~~~~~~~~~
-
-error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds
-  --> $DIR/issue-109141.rs:6:9
-   |
-LL |     fn a(&self) -> impl Iterator {
-   |          -----     ------------- opaque type defined here
-   |          |
-   |          hidden type `std::slice::IterMut<'_, [u8; {const error}]>` captures the anonymous lifetime defined here
-LL |         self.0.iter_mut()
-   |         ^^^^^^^^^^^^^^^^^
-   |
-help: add a `use<...>` bound to explicitly capture `'_`
-   |
-LL |     fn a(&self) -> impl Iterator + use<'_> {
-   |                                  +++++++++
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0425, E0596, E0700.
-For more information about an error, try `rustc --explain E0425`.
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
index 7209290a36e..56b8acbf88c 100644
--- a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
+++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
@@ -2,7 +2,6 @@
 #![allow(incomplete_features)]
 
 type Foo = impl Sized;
-//~^ ERROR: unconstrained opaque type
 
 fn with_bound<const N: usize>() -> Foo
 where
diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
index c7a266205b4..e9fb8c0f403 100644
--- a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/opaque_type.rs:11:17
+  --> $DIR/opaque_type.rs:10:17
    |
 LL | type Foo = impl Sized;
    |            ---------- the found opaque type
@@ -11,20 +11,12 @@ LL |     let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
            found opaque type `Foo`
 
 error[E0605]: non-primitive cast: `usize` as `Foo`
-  --> $DIR/opaque_type.rs:11:17
+  --> $DIR/opaque_type.rs:10:17
    |
 LL |     let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
    |                 ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 
-error: unconstrained opaque type
-  --> $DIR/opaque_type.rs:4:12
-   |
-LL | type Foo = impl Sized;
-   |            ^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same module
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0308, E0605.
 For more information about an error, try `rustc --explain E0308`.