about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2021-09-02 19:10:24 +0200
committerGitHub <noreply@github.com>2021-09-02 19:10:24 +0200
commitc082e157cae3307ea991e259758b26e855362b8e (patch)
treee5cb85b9959986a5cd3242c34738ecdd45abea46
parent8f88d44b0dbeefb7e5683cfcee38763427e9cb03 (diff)
parentf825d6c6ccb5bc1eab9dfda96d3189f7092eb867 (diff)
downloadrust-c082e157cae3307ea991e259758b26e855362b8e.tar.gz
rust-c082e157cae3307ea991e259758b26e855362b8e.zip
Rollup merge of #88592 - b-naber:region_substs, r=oli-obk
Fix ICE in const check

Fixes https://github.com/rust-lang/rust/issues/88433
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/check.rs36
-rw-r--r--src/test/ui/const-generics/const_trait_fn-issue-88433.rs26
2 files changed, 45 insertions, 17 deletions
diff --git a/compiler/rustc_mir/src/transform/check_consts/check.rs b/compiler/rustc_mir/src/transform/check_consts/check.rs
index 2b748062cdf..0c381276823 100644
--- a/compiler/rustc_mir/src/transform/check_consts/check.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/check.rs
@@ -9,7 +9,7 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::cast::CastTy;
-use rustc_middle::ty::subst::GenericArgKind;
+use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
 use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
 use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
 use rustc_span::{sym, Span, Symbol};
@@ -793,7 +793,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
 
                 let fn_ty = func.ty(body, tcx);
 
-                let (mut callee, substs) = match *fn_ty.kind() {
+                let (mut callee, mut substs) = match *fn_ty.kind() {
                     ty::FnDef(def_id, substs) => (def_id, substs),
 
                     ty::FnPtr(_) => {
@@ -846,29 +846,31 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
                                 .iter()
                                 .find(|did| tcx.item_name(**did) == callee_name)
                             {
+                                // using internal substs is ok here, since this is only
+                                // used for the `resolve` call below
+                                substs = InternalSubsts::identity_for_item(tcx, did);
                                 callee = did;
                             }
                         }
-                        _ => {
-                            if !tcx.is_const_fn_raw(callee) {
-                                // At this point, it is only legal when the caller is marked with
-                                // #[default_method_body_is_const], and the callee is in the same
-                                // trait.
-                                let callee_trait = tcx.trait_of_item(callee);
-                                if callee_trait.is_some() {
-                                    if tcx.has_attr(caller, sym::default_method_body_is_const) {
-                                        if tcx.trait_of_item(caller) == callee_trait {
-                                            nonconst_call_permission = true;
-                                        }
+                        _ if !tcx.is_const_fn_raw(callee) => {
+                            // At this point, it is only legal when the caller is marked with
+                            // #[default_method_body_is_const], and the callee is in the same
+                            // trait.
+                            let callee_trait = tcx.trait_of_item(callee);
+                            if callee_trait.is_some() {
+                                if tcx.has_attr(caller, sym::default_method_body_is_const) {
+                                    if tcx.trait_of_item(caller) == callee_trait {
+                                        nonconst_call_permission = true;
                                     }
                                 }
+                            }
 
-                                if !nonconst_call_permission {
-                                    self.check_op(ops::FnCallNonConst);
-                                    return;
-                                }
+                            if !nonconst_call_permission {
+                                self.check_op(ops::FnCallNonConst);
+                                return;
                             }
                         }
+                        _ => {}
                     }
 
                     // Resolve a trait method call to its concrete implementation, which may be in a
diff --git a/src/test/ui/const-generics/const_trait_fn-issue-88433.rs b/src/test/ui/const-generics/const_trait_fn-issue-88433.rs
new file mode 100644
index 00000000000..8724fa69825
--- /dev/null
+++ b/src/test/ui/const-generics/const_trait_fn-issue-88433.rs
@@ -0,0 +1,26 @@
+// build-pass
+
+#![feature(const_trait_impl)]
+
+trait Func<T> {
+    type Output;
+
+    fn call_once(self, arg: T) -> Self::Output;
+}
+
+
+struct Closure;
+
+impl const Func<&usize> for Closure {
+    type Output = usize;
+
+    fn call_once(self, arg: &usize) -> Self::Output {
+        *arg
+    }
+}
+
+enum Bug<T = [(); Closure.call_once(&0) ]> {
+    V(T),
+}
+
+fn main() {}