about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2021-07-26 17:25:01 +0800
committerDeadbeef <ent3rm4n@gmail.com>2021-08-13 09:28:52 +0000
commit1fa712d0ba4e1db6fa22cad00182d009afeb7770 (patch)
tree7083c8dba065ee5e9ff36c77dda492b978ab4ca6
parent8c2a1e8e432d092896cf0487eca5de324fc06bfc (diff)
downloadrust-1fa712d0ba4e1db6fa22cad00182d009afeb7770.tar.gz
rust-1fa712d0ba4e1db6fa22cad00182d009afeb7770.zip
Make assoc types work with `?const `opt=out
-rw-r--r--compiler/rustc_hir/src/hir.rs10
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs23
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/mod.rs2
-rw-r--r--compiler/rustc_typeck/src/check/inherited.rs2
-rw-r--r--compiler/rustc_typeck/src/collect.rs2
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs10
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr2
7 files changed, 24 insertions, 27 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 9fc39afac9f..3879d605292 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3261,8 +3261,13 @@ impl<'hir> Node<'hir> {
         }
     }
 
-    /// Returns `Constness::Const` when this node is a const fn/impl/item.
-    pub fn constness(&self) -> Constness {
+    /// Returns `Constness::Const` when this node is a const fn/impl/item,
+    ///
+    /// HACK(fee1-dead): or an associated type in a trait. This works because
+    /// only typeck cares about const trait predicates, so although the predicates
+    /// query would return const predicates when it does not need to be const,
+    /// it wouldn't have any effect.
+    pub fn constness_for_typeck(&self) -> Constness {
         match self {
             Node::Item(Item {
                 kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
@@ -3280,6 +3285,7 @@ impl<'hir> Node<'hir> {
 
             Node::Item(Item { kind: ItemKind::Const(..), .. })
             | Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
+            | Node::TraitItem(TraitItem { kind: TraitItemKind::Type(..), .. })
             | Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const,
 
             _ => Constness::NotConst,
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index a2ffb30f43b..316a097556a 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -1292,28 +1292,12 @@ pub fn check_type_bounds<'tcx>(
     };
 
     tcx.infer_ctxt().enter(move |infcx| {
-        // if the item is inside a const impl, we transform the predicates to be const.
         let constness = impl_ty
             .container
             .impl_def_id()
             .map(|did| tcx.impl_constness(did))
             .unwrap_or(hir::Constness::NotConst);
 
-        let pred_map = match constness {
-            hir::Constness::NotConst => |p, _| p,
-            hir::Constness::Const => |p: ty::Predicate<'tcx>, tcx: TyCtxt<'tcx>| {
-                p.kind()
-                    .map_bound(|kind| match kind {
-                        ty::PredicateKind::Trait(mut tp) => {
-                            tp.constness = hir::Constness::Const;
-                            ty::PredicateKind::Trait(tp)
-                        }
-                        kind => kind,
-                    })
-                    .to_predicate(tcx)
-            },
-        };
-
         let inh = Inherited::with_constness(infcx, impl_ty.def_id.expect_local(), constness);
         let infcx = &inh.infcx;
         let mut selcx = traits::SelectionContext::new(&infcx);
@@ -1332,7 +1316,7 @@ pub fn check_type_bounds<'tcx>(
             .explicit_item_bounds(trait_ty.def_id)
             .iter()
             .map(|&(bound, span)| {
-                let concrete_ty_bound = pred_map(bound.subst(tcx, rebased_substs), tcx);
+                let concrete_ty_bound = bound.subst(tcx, rebased_substs);
                 debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
 
                 traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
@@ -1350,10 +1334,7 @@ pub fn check_type_bounds<'tcx>(
             debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate);
             obligation.predicate = normalized_predicate;
 
-            inh.register_predicates(obligations.into_iter().map(|mut o| {
-                o.predicate = pred_map(o.predicate, tcx);
-                o
-            }));
+            inh.register_predicates(obligations);
             inh.register_predicate(obligation);
         }
 
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
index 75705e92e54..c0ecee155c6 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
@@ -174,7 +174,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
     }
 
     fn default_constness_for_trait_bounds(&self) -> hir::Constness {
-        self.tcx.hir().get(self.body_id).constness()
+        self.tcx.hir().get(self.body_id).constness_for_typeck()
     }
 
     fn get_type_parameter_bounds(
diff --git a/compiler/rustc_typeck/src/check/inherited.rs b/compiler/rustc_typeck/src/check/inherited.rs
index 9d9c77ec072..6006c8f7513 100644
--- a/compiler/rustc_typeck/src/check/inherited.rs
+++ b/compiler/rustc_typeck/src/check/inherited.rs
@@ -98,7 +98,7 @@ impl Inherited<'a, 'tcx> {
     pub(super) fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
         let tcx = infcx.tcx;
         let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
-        Self::with_constness(infcx, def_id, tcx.hir().get(item_id).constness())
+        Self::with_constness(infcx, def_id, tcx.hir().get(item_id).constness_for_typeck())
     }
 
     pub(super) fn with_constness(
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index c16b7bab3a3..9fbf5ab8533 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -364,7 +364,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
     }
 
     fn default_constness_for_trait_bounds(&self) -> hir::Constness {
-        self.node().constness()
+        self.node().constness_for_typeck()
     }
 
     fn get_type_parameter_bounds(
diff --git a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs
index 8d72adb6b61..1dbd000afd7 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs
@@ -1,5 +1,7 @@
 // FIXME(fee1-dead): this should have a better error message
 #![feature(const_trait_impl)]
+#![feature(const_trait_bound_opt_out)]
+#![allow(incomplete_features)]
 
 struct NonConstAdd(i32);
 
@@ -20,4 +22,12 @@ impl const Foo for NonConstAdd {
     //~^ ERROR
 }
 
+trait Baz {
+    type Qux: ?const std::ops::Add;
+}
+
+impl const Baz for NonConstAdd {
+    type Qux = NonConstAdd; // OK
+}
+
 fn main() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
index 1fdc963e7b2..0cbeb71d235 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
@@ -1,5 +1,5 @@
 error[E0277]: cannot add `NonConstAdd` to `NonConstAdd`
-  --> $DIR/assoc-type.rs:19:5
+  --> $DIR/assoc-type.rs:21:5
    |
 LL |     type Bar: std::ops::Add;
    |               ------------- required by this bound in `Foo::Bar`