about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs8
-rw-r--r--compiler/rustc_hir/src/hir.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs16
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.rs18
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr59
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs27
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr69
8 files changed, 215 insertions, 5 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 1e51449e70c..04a8e2b134a 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1217,7 +1217,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                     hir_id: this.lower_node_id(node_id),
                                     body: this.lower_const_body(path_expr.span, Some(&path_expr)),
                                 });
-                                return GenericArg::Const(ConstArg { value: ct, span });
+                                return GenericArg::Const(ConstArg {
+                                    value: ct,
+                                    span,
+                                    is_desugared_from_effects: false,
+                                });
                             }
                         }
                     }
@@ -1228,6 +1232,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             ast::GenericArg::Const(ct) => GenericArg::Const(ConstArg {
                 value: self.lower_anon_const(&ct),
                 span: self.lower_span(ct.value.span),
+                is_desugared_from_effects: false,
             }),
         }
     }
@@ -2525,6 +2530,7 @@ impl<'hir> GenericArgsCtor<'hir> {
         self.args.push(hir::GenericArg::Const(hir::ConstArg {
             value: hir::AnonConst { def_id, hir_id, body },
             span,
+            is_desugared_from_effects: true,
         }))
     }
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 259af4f565b..17c6352ce24 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -246,6 +246,8 @@ impl<'hir> PathSegment<'hir> {
 pub struct ConstArg {
     pub value: AnonConst,
     pub span: Span,
+    /// Indicates whether this comes from a `~const` desugaring.
+    pub is_desugared_from_effects: bool,
 }
 
 #[derive(Clone, Copy, Debug, HashStable_Generic)]
@@ -400,7 +402,14 @@ impl<'hir> GenericArgs<'hir> {
     /// This function returns the number of type and const generic params.
     /// It should only be used for diagnostics.
     pub fn num_generic_params(&self) -> usize {
-        self.args.iter().filter(|arg| !matches!(arg, GenericArg::Lifetime(_))).count()
+        self.args
+            .iter()
+            .filter(|arg| match arg {
+                GenericArg::Lifetime(_)
+                | GenericArg::Const(ConstArg { is_desugared_from_effects: true, .. }) => false,
+                _ => true,
+            })
+            .count()
     }
 
     /// The span encompassing the text inside the surrounding brackets.
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 7f0c0b961e4..d29a27eced0 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -429,6 +429,14 @@ pub(crate) fn check_generic_arg_count(
         .filter(|param| matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. }))
         .count();
     let named_type_param_count = param_counts.types - has_self as usize - synth_type_param_count;
+    let synth_const_param_count = gen_params
+        .params
+        .iter()
+        .filter(|param| {
+            matches!(param.kind, ty::GenericParamDefKind::Const { is_host_effect: true, .. })
+        })
+        .count();
+    let named_const_param_count = param_counts.consts - synth_const_param_count;
     let infer_lifetimes =
         (gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params();
 
@@ -573,11 +581,13 @@ pub(crate) fn check_generic_arg_count(
         debug!(?expected_min);
         debug!(arg_counts.lifetimes=?gen_args.num_lifetime_params());
 
+        let provided = gen_args.num_generic_params();
+
         check_types_and_consts(
             expected_min,
-            param_counts.consts + named_type_param_count,
-            param_counts.consts + named_type_param_count + synth_type_param_count,
-            gen_args.num_generic_params(),
+            named_const_param_count + named_type_param_count,
+            named_const_param_count + named_type_param_count + synth_type_param_count,
+            provided,
             param_counts.lifetimes + has_self as usize,
             gen_args.num_lifetime_params(),
         )
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs
new file mode 100644
index 00000000000..a74c50cc8fa
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs
@@ -0,0 +1,12 @@
+#![feature(const_trait_impl, effects)]
+
+pub const fn foo() {}
+
+#[const_trait]
+pub trait Bar {
+    fn bar();
+}
+
+impl Bar for () {
+    fn bar() {}
+}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.rs
new file mode 100644
index 00000000000..8e4850197de
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.rs
@@ -0,0 +1,18 @@
+// aux-build: cross-crate.rs
+extern crate cross_crate;
+
+use cross_crate::{Bar, foo};
+
+fn main() {
+    foo::<true>();
+    //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
+    <() as Bar<true>>::bar();
+    //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
+}
+
+const FOO: () = {
+    foo::<false>();
+    //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
+    <() as Bar<false>>::bar();
+    //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
+};
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr
new file mode 100644
index 00000000000..cc870ad336c
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr
@@ -0,0 +1,59 @@
+error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params-cross-crate.rs:14:5
+   |
+LL |     foo::<false>();
+   |     ^^^--------- help: remove these generics
+   |     |
+   |     expected 0 generic arguments
+   |
+note: function defined here, with 0 generic parameters
+  --> $DIR/auxiliary/cross-crate.rs:3:14
+   |
+LL | pub const fn foo() {}
+   |              ^^^
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params-cross-crate.rs:16:12
+   |
+LL |     <() as Bar<false>>::bar();
+   |            ^^^------- help: remove these generics
+   |            |
+   |            expected 0 generic arguments
+   |
+note: trait defined here, with 0 generic parameters
+  --> $DIR/auxiliary/cross-crate.rs:6:11
+   |
+LL | pub trait Bar {
+   |           ^^^
+
+error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params-cross-crate.rs:7:5
+   |
+LL |     foo::<true>();
+   |     ^^^-------- help: remove these generics
+   |     |
+   |     expected 0 generic arguments
+   |
+note: function defined here, with 0 generic parameters
+  --> $DIR/auxiliary/cross-crate.rs:3:14
+   |
+LL | pub const fn foo() {}
+   |              ^^^
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params-cross-crate.rs:9:12
+   |
+LL |     <() as Bar<true>>::bar();
+   |            ^^^------ help: remove these generics
+   |            |
+   |            expected 0 generic arguments
+   |
+note: trait defined here, with 0 generic parameters
+  --> $DIR/auxiliary/cross-crate.rs:6:11
+   |
+LL | pub trait Bar {
+   |           ^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs
new file mode 100644
index 00000000000..929da1ca8fa
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.rs
@@ -0,0 +1,27 @@
+#![feature(const_trait_impl, effects)]
+
+const fn foo() {}
+
+#[const_trait]
+trait Bar {
+    fn bar();
+}
+
+impl Bar for () {
+    fn bar() {}
+}
+
+fn main() {
+    foo::<true>();
+    //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
+    <() as Bar<true>>::bar();
+    //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
+}
+
+const FOO: () = {
+    foo::<false>();
+    //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
+    <() as Bar<false>>::bar();
+    //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
+    //~| ERROR: mismatched types
+};
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr
new file mode 100644
index 00000000000..0745d0304b9
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr
@@ -0,0 +1,69 @@
+error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params.rs:22:5
+   |
+LL |     foo::<false>();
+   |     ^^^--------- help: remove these generics
+   |     |
+   |     expected 0 generic arguments
+   |
+note: function defined here, with 0 generic parameters
+  --> $DIR/no-explicit-const-params.rs:3:10
+   |
+LL | const fn foo() {}
+   |          ^^^
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params.rs:24:12
+   |
+LL |     <() as Bar<false>>::bar();
+   |            ^^^------- help: remove these generics
+   |            |
+   |            expected 0 generic arguments
+   |
+note: trait defined here, with 0 generic parameters
+  --> $DIR/no-explicit-const-params.rs:6:7
+   |
+LL | trait Bar {
+   |       ^^^
+
+error[E0308]: mismatched types
+  --> $DIR/no-explicit-const-params.rs:24:5
+   |
+LL |     <() as Bar<false>>::bar();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `false`, found `true`
+   |
+   = note: expected constant `false`
+              found constant `true`
+
+error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params.rs:15:5
+   |
+LL |     foo::<true>();
+   |     ^^^-------- help: remove these generics
+   |     |
+   |     expected 0 generic arguments
+   |
+note: function defined here, with 0 generic parameters
+  --> $DIR/no-explicit-const-params.rs:3:10
+   |
+LL | const fn foo() {}
+   |          ^^^
+
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/no-explicit-const-params.rs:17:12
+   |
+LL |     <() as Bar<true>>::bar();
+   |            ^^^------ help: remove these generics
+   |            |
+   |            expected 0 generic arguments
+   |
+note: trait defined here, with 0 generic parameters
+  --> $DIR/no-explicit-const-params.rs:6:7
+   |
+LL | trait Bar {
+   |       ^^^
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0107, E0308.
+For more information about an error, try `rustc --explain E0107`.