about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEllen <supbscripter@gmail.com>2021-07-10 14:53:37 +0100
committerEllen <supbscripter@gmail.com>2021-07-10 17:29:11 +0100
commitb44be27999d26ee5f6712704e5d0535c2ea08e70 (patch)
tree8f2b282a29d1754970b79088aad00221825a2551
parent05dcb7874a5a8c84fe943dcbae12010ba5a40c25 (diff)
downloadrust-b44be27999d26ee5f6712704e5d0535c2ea08e70.tar.gz
rust-b44be27999d26ee5f6712704e5d0535c2ea08e70.zip
Moves changes to explicit_preds_of/inferred_outlives_of/generics_of
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs33
-rw-r--r--compiler/rustc_typeck/src/collect.rs44
-rw-r--r--compiler/rustc_typeck/src/outlives/mod.rs16
-rw-r--r--src/test/ui/const-generics/defaults/cec-build-subst-ice.stderr11
4 files changed, 71 insertions, 33 deletions
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 16ec935ba1a..c78151271c1 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -85,10 +85,7 @@ impl<'tcx> Const<'tcx> {
             _ => expr,
         };
 
-        use hir::{
-            def::DefKind::ConstParam, def::Res, ExprKind, GenericParam, GenericParamKind, Node,
-            Path, QPath,
-        };
+        use hir::{def::DefKind::ConstParam, def::Res, ExprKind, Path, QPath};
         let val = match expr.kind {
             ExprKind::Path(QPath::Resolved(_, &Path { res: Res::Def(ConstParam, def_id), .. })) => {
                 // Find the name and index of the const parameter by indexing the generics of
@@ -103,33 +100,7 @@ impl<'tcx> Const<'tcx> {
             }
             _ => ty::ConstKind::Unevaluated(ty::Unevaluated {
                 def: def.to_global(),
-                substs: {
-                    let ct_hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
-                    let parent_id = tcx.hir().get_parent_node(ct_hir_id);
-                    match tcx.hir().get(parent_id) {
-                        // If this anon ct is a cg default we should only provide non-fwd declared params
-                        // https://github.com/rust-lang/rust/issues/83938
-                        Node::GenericParam(GenericParam {
-                            hir_id: param_id,
-                            kind: GenericParamKind::Const { .. },
-                            ..
-                        }) => {
-                            let item_id = tcx.hir().get_parent_node(*param_id);
-                            let item_def_id = tcx.hir().local_def_id(item_id);
-                            let generics = tcx.generics_of(item_def_id.to_def_id());
-                            let param_def = tcx.hir().local_def_id(*param_id).to_def_id();
-                            let param_def_idx = generics.param_def_id_to_index[&param_def];
-                            let substs = generics
-                                .params
-                                .iter()
-                                .map(|param| tcx.mk_param_from_def(param))
-                                .take(param_def_idx as usize)
-                                .collect::<smallvec::SmallVec<[_; 8]>>();
-                            tcx.intern_substs(&substs)
-                        }
-                        _ => InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
-                    }
-                },
+                substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
                 promoted: None,
             }),
         };
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 583ba9392f0..924a0b8410a 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -1441,6 +1441,32 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
                 // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
                 None
             } else if tcx.lazy_normalization() {
+                // Only provide backwards declared generics to cg defaults (#83938)
+                if let Node::GenericParam(GenericParam {
+                    hir_id: param_id,
+                    kind: GenericParamKind::Const { .. },
+                    ..
+                }) = tcx.hir().get(tcx.hir().get_parent_node(hir_id))
+                {
+                    let item_id = tcx.hir().get_parent_node(*param_id);
+                    let item_def_id = tcx.hir().local_def_id(item_id);
+                    let generics = tcx.generics_of(item_def_id.to_def_id());
+                    let param_def = tcx.hir().local_def_id(*param_id).to_def_id();
+                    let param_def_idx = generics.param_def_id_to_index[&param_def];
+                    let params = generics.params[..param_def_idx as usize].to_owned();
+                    let param_def_id_to_index =
+                        params.iter().map(|param| (param.def_id, param.index)).collect();
+
+                    return ty::Generics {
+                        parent: generics.parent,
+                        parent_count: generics.parent_count,
+                        params,
+                        param_def_id_to_index,
+                        has_self: generics.has_self,
+                        has_late_bound_regions: generics.has_late_bound_regions,
+                    };
+                }
+
                 // HACK(eddyb) this provides the correct generics when
                 // `feature(const_generics)` is enabled, so that const expressions
                 // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
@@ -2359,7 +2385,8 @@ fn trait_explicit_predicates_and_bounds(
 }
 
 fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
-    if let DefKind::Trait = tcx.def_kind(def_id) {
+    let def_kind = tcx.def_kind(def_id);
+    if let DefKind::Trait = def_kind {
         // Remove bounds on associated types from the predicates, they will be
         // returned by `explicit_item_bounds`.
         let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id.expect_local());
@@ -2404,6 +2431,21 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
             }
         }
     } else {
+        if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() {
+            // Provide predicates of parent item of cg defaults manually
+            // as generics_of doesn't return a parent for the generics
+            let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+            if let Node::GenericParam(hir::GenericParam {
+                hir_id: param_id,
+                kind: hir::GenericParamKind::Const { .. },
+                ..
+            }) = tcx.hir().get(tcx.hir().get_parent_node(hir_id))
+            {
+                let item_id = tcx.hir().get_parent_node(*param_id);
+                let item_def_id = tcx.hir().local_def_id(item_id).to_def_id();
+                return tcx.explicit_predicates_of(item_def_id);
+            }
+        }
         gather_explicit_predicates_of(tcx, def_id)
     }
 }
diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs
index d7eb31c2abe..c2f8525f7ab 100644
--- a/compiler/rustc_typeck/src/outlives/mod.rs
+++ b/compiler/rustc_typeck/src/outlives/mod.rs
@@ -20,6 +20,22 @@ pub fn provide(providers: &mut Providers) {
 fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate<'_>, Span)] {
     let id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local());
 
+    if matches!(tcx.def_kind(item_def_id), hir::def::DefKind::AnonConst) && tcx.lazy_normalization()
+    {
+        // Provide inferred outlive preds of parent item of cg defaults manually
+        // as generics_of doesn't return a parent for the generics
+        if let Node::GenericParam(hir::GenericParam {
+            hir_id: param_id,
+            kind: hir::GenericParamKind::Const { .. },
+            ..
+        }) = tcx.hir().get(tcx.hir().get_parent_node(id))
+        {
+            let item_id = tcx.hir().get_parent_node(*param_id);
+            let item_def_id = tcx.hir().local_def_id(item_id).to_def_id();
+            return tcx.inferred_outlives_of(item_def_id);
+        }
+    }
+
     match tcx.hir().get(id) {
         Node::Item(item) => match item.kind {
             hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) => {
diff --git a/src/test/ui/const-generics/defaults/cec-build-subst-ice.stderr b/src/test/ui/const-generics/defaults/cec-build-subst-ice.stderr
index 0508007412c..30a01d48c4c 100644
--- a/src/test/ui/const-generics/defaults/cec-build-subst-ice.stderr
+++ b/src/test/ui/const-generics/defaults/cec-build-subst-ice.stderr
@@ -8,5 +8,14 @@ LL | pub fn foo<const N1: usize>() -> Bar<N1> { loop {} }
    |
    = help: try adding a `where` bound using this expression: `where [(); { N + 1 }]:`
 
-error: aborting due to previous error
+error: unconstrained generic constant
+  --> $DIR/cec-build-subst-ice.rs:15:8
+   |
+LL | type Alias<T, const N: usize, const NP: usize = {N+1usize}> = [T; NP];
+   |                                                 ---------- required by this bound in `Alias::{constant#0}`
+LL | fn alias<T, const N: usize>(_: [T; N], _: T)
+LL |     -> Alias<T, N>
+   |        ^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); {N+1usize}]:`