diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1e51449e70cc6..04a8e2b134a60 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 259af4f565bda..17c6352ce24c2 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 7f0c0b961e4e8..d29a27eced0e7 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 0000000000000..a74c50cc8fa47 --- /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 0000000000000..8e4850197de5e --- /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::(); + //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied + <() as Bar>::bar(); + //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied +} + +const FOO: () = { + foo::(); + //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied + <() as Bar>::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 0000000000000..cc870ad336cd1 --- /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::(); + | ^^^--------- 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>::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::(); + | ^^^-------- 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>::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 0000000000000..929da1ca8fa99 --- /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::(); + //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied + <() as Bar>::bar(); + //~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied +} + +const FOO: () = { + foo::(); + //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied + <() as Bar>::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 0000000000000..0745d0304b9e6 --- /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::(); + | ^^^--------- 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>::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>::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::(); + | ^^^-------- 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>::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`.