Skip to content

Commit 98e73bd

Browse files
committed
mgca always resolve params
1 parent c17b8fb commit 98e73bd

File tree

8 files changed

+87
-81
lines changed

8 files changed

+87
-81
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,6 +2378,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23782378
let expr = &tcx.hir_body(anon.body).value;
23792379
debug!(?expr);
23802380

2381+
// If the rhs is an anon const naming generics it shouldn't have
2382+
// access to then we lower to `ConstKind::Error`.
2383+
if let ty::AnonConstKind::MCG = tcx.anon_const_kind(anon.def_id)
2384+
&& let Err(e) = tcx.hir_const_arg_anon_check_invalid_param_uses(anon.def_id)
2385+
{
2386+
return ty::Const::new_error(tcx, e);
2387+
}
2388+
23812389
// FIXME(generic_const_parameter_types): We should use the proper generic args
23822390
// here. It's only used as a hint for literals so doesn't matter too much to use the right
23832391
// generic arguments, just weaker type inference.

compiler/rustc_hir_typeck/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ fn typeck_with_inspect<'tcx>(
117117
return tcx.typeck(typeck_root_def_id);
118118
}
119119

120+
if let DefKind::AnonConst = tcx.def_kind(def_id)
121+
&& let ty::AnonConstKind::MCG = tcx.anon_const_kind(def_id)
122+
&& let Err(e) = tcx.hir_const_arg_anon_check_invalid_param_uses(def_id)
123+
{
124+
e.raise_fatal();
125+
}
126+
120127
let id = tcx.local_def_id_to_hir_id(def_id);
121128
let node = tcx.hir_node(id);
122129
let span = tcx.def_span(def_id);

compiler/rustc_middle/src/hir/map.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//! eliminated, and all its methods are now on `TyCtxt`. But the module name
33
//! stays as `map` because there isn't an obviously better name for it.
44
5+
use std::ops::ControlFlow;
6+
57
use rustc_abi::ExternAbi;
68
use rustc_ast::visit::{VisitorResult, walk_list};
79
use rustc_data_structures::fingerprint::Fingerprint;
@@ -1087,6 +1089,47 @@ impl<'tcx> TyCtxt<'tcx> {
10871089

10881090
None
10891091
}
1092+
1093+
pub fn hir_const_arg_anon_check_invalid_param_uses(
1094+
self,
1095+
anon: LocalDefId,
1096+
) -> Result<(), ErrorGuaranteed> {
1097+
struct GenericParamVisitor<'tcx>(TyCtxt<'tcx>);
1098+
impl<'tcx> Visitor<'tcx> for GenericParamVisitor<'tcx> {
1099+
type NestedFilter = nested_filter::OnlyBodies;
1100+
type Result = ControlFlow<ErrorGuaranteed>;
1101+
1102+
fn maybe_tcx(&mut self) -> TyCtxt<'tcx> {
1103+
self.0
1104+
}
1105+
1106+
fn visit_path(
1107+
&mut self,
1108+
path: &crate::hir::Path<'tcx>,
1109+
_id: HirId,
1110+
) -> ControlFlow<ErrorGuaranteed> {
1111+
if let Res::Def(
1112+
DefKind::TyParam | DefKind::ConstParam | DefKind::LifetimeParam,
1113+
_,
1114+
) = path.res
1115+
{
1116+
let e = self.0.dcx().struct_span_err(
1117+
path.span,
1118+
"generic parameters may not be used in const operations",
1119+
);
1120+
return ControlFlow::Break(e.emit());
1121+
}
1122+
1123+
intravisit::walk_path(self, path)
1124+
}
1125+
}
1126+
1127+
let body = self.hir_maybe_body_owned_by(anon).unwrap();
1128+
match GenericParamVisitor(self).visit_expr(&body.value) {
1129+
ControlFlow::Break(e) => Err(e),
1130+
ControlFlow::Continue(()) => Ok(()),
1131+
}
1132+
}
10901133
}
10911134

10921135
impl<'tcx> intravisit::HirTyCtxt<'tcx> for TyCtxt<'tcx> {

compiler/rustc_resolve/src/late.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4839,12 +4839,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
48394839
constant, anon_const_kind
48404840
);
48414841

4842-
let is_trivial_const_arg = if self.r.tcx.features().min_generic_const_args() {
4843-
matches!(constant.mgca_disambiguation, MgcaDisambiguation::Direct)
4844-
} else {
4845-
constant.value.is_potential_trivial_const_arg()
4846-
};
4847-
4842+
let is_trivial_const_arg = constant.value.is_potential_trivial_const_arg();
48484843
self.resolve_anon_const_manual(is_trivial_const_arg, anon_const_kind, |this| {
48494844
this.resolve_expr(&constant.value, None)
48504845
})
@@ -4874,7 +4869,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
48744869
AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes,
48754870
AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
48764871
AnonConstKind::ConstArg(_) => {
4877-
if self.r.tcx.features().generic_const_exprs() || is_trivial_const_arg {
4872+
if self.r.tcx.features().generic_const_exprs()
4873+
|| self.r.tcx.features().min_generic_const_args()
4874+
|| is_trivial_const_arg
4875+
{
48784876
ConstantHasGenerics::Yes
48794877
} else {
48804878
ConstantHasGenerics::No(NoConstantGenericsReason::NonTrivialConstArg)

tests/ui/const-generics/mgca/explicit_anon_consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type Adt1<const N: usize> = Foo<N>;
77
type Adt2<const N: usize> = Foo<{ N }>;
88
type Adt3<const N: usize> = Foo<const { N }>;
99
//~^ ERROR: generic parameters may not be used in const operations
10+
//~^^ ERROR generic parameters may not be used in const operations
1011
type Adt4<const N: usize> = Foo<{ 1 + 1 }>;
1112
//~^ ERROR: complex const arguments must be placed inside of a `const` block
1213
type Adt5<const N: usize> = Foo<const { 1 + 1 }>;

tests/ui/const-generics/mgca/explicit_anon_consts.stderr

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,29 @@
1-
error: generic parameters may not be used in const operations
2-
--> $DIR/explicit_anon_consts.rs:8:41
3-
|
4-
LL | type Adt3<const N: usize> = Foo<const { N }>;
5-
| ^ cannot perform const operation using `N`
6-
|
7-
= help: const parameters may only be used as standalone arguments here, i.e. `N`
8-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
9-
10-
error: generic parameters may not be used in const operations
11-
--> $DIR/explicit_anon_consts.rs:16:42
12-
|
13-
LL | type Arr3<const N: usize> = [(); const { N }];
14-
| ^ cannot perform const operation using `N`
15-
|
16-
= help: const parameters may only be used as standalone arguments here, i.e. `N`
17-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
18-
19-
error: generic parameters may not be used in const operations
20-
--> $DIR/explicit_anon_consts.rs:25:27
21-
|
22-
LL | let _3 = [(); const { N }];
23-
| ^ cannot perform const operation using `N`
24-
|
25-
= help: const parameters may only be used as standalone arguments here, i.e. `N`
26-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
27-
28-
error: generic parameters may not be used in const operations
29-
--> $DIR/explicit_anon_consts.rs:37:46
30-
|
31-
LL | const ITEM3<const N: usize>: usize = const { N };
32-
| ^ cannot perform const operation using `N`
33-
|
34-
= help: const parameters may only be used as standalone arguments here, i.e. `N`
35-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
36-
37-
error: generic parameters may not be used in const operations
38-
--> $DIR/explicit_anon_consts.rs:55:31
39-
|
40-
LL | T3: Trait<ASSOC = const { N }>,
41-
| ^ cannot perform const operation using `N`
42-
|
43-
= help: const parameters may only be used as standalone arguments here, i.e. `N`
44-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
45-
461
error: complex const arguments must be placed inside of a `const` block
47-
--> $DIR/explicit_anon_consts.rs:10:33
2+
--> $DIR/explicit_anon_consts.rs:11:33
483
|
494
LL | type Adt4<const N: usize> = Foo<{ 1 + 1 }>;
505
| ^^^^^^^^^
516

527
error: complex const arguments must be placed inside of a `const` block
53-
--> $DIR/explicit_anon_consts.rs:18:34
8+
--> $DIR/explicit_anon_consts.rs:19:34
549
|
5510
LL | type Arr4<const N: usize> = [(); 1 + 1];
5611
| ^^^^^
5712

5813
error: complex const arguments must be placed inside of a `const` block
59-
--> $DIR/explicit_anon_consts.rs:27:19
14+
--> $DIR/explicit_anon_consts.rs:28:19
6015
|
6116
LL | let _4 = [(); 1 + 1];
6217
| ^^^^^
6318

6419
error: complex const arguments must be placed inside of a `const` block
65-
--> $DIR/explicit_anon_consts.rs:40:38
20+
--> $DIR/explicit_anon_consts.rs:41:38
6621
|
6722
LL | const ITEM4<const N: usize>: usize = { 1 + 1 };
6823
| ^^^^^^^^^
6924

7025
error: complex const arguments must be placed inside of a `const` block
71-
--> $DIR/explicit_anon_consts.rs:57:23
26+
--> $DIR/explicit_anon_consts.rs:58:23
7227
|
7328
LL | T4: Trait<ASSOC = { 1 + 1 }>,
7429
| ^^^^^^^^^

tests/ui/const-generics/mgca/type_const-on-generic-expr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#[type_const]
55
const FREE1<T>: usize = const { std::mem::size_of::<T>() };
66
//~^ ERROR generic parameters may not be used in const operations
7+
//~^^ ERROR generic parameters may not be used in const operations
78
#[type_const]
89
const FREE2<const I: usize>: usize = const { I + 1 };
910
//~^ ERROR generic parameters may not be used in const operations

tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,39 @@ error: generic parameters may not be used in const operations
22
--> $DIR/type_const-on-generic-expr.rs:5:53
33
|
44
LL | const FREE1<T>: usize = const { std::mem::size_of::<T>() };
5-
| ^ cannot perform const operation using `T`
6-
|
7-
= note: type parameters may not be used in const expressions
8-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
5+
| ^
96

107
error: generic parameters may not be used in const operations
11-
--> $DIR/type_const-on-generic-expr.rs:8:46
8+
--> $DIR/type_const-on-generic-expr.rs:9:46
129
|
1310
LL | const FREE2<const I: usize>: usize = const { I + 1 };
14-
| ^ cannot perform const operation using `I`
15-
|
16-
= help: const parameters may only be used as standalone arguments here, i.e. `I`
17-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
11+
| ^
1812

1913
error: generic parameters may not be used in const operations
20-
--> $DIR/type_const-on-generic-expr.rs:24:54
14+
--> $DIR/type_const-on-generic-expr.rs:25:54
2115
|
2216
LL | const N1<T>: usize = const { std::mem::size_of::<T>() };
23-
| ^ cannot perform const operation using `T`
24-
|
25-
= note: type parameters may not be used in const expressions
26-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
17+
| ^
2718

2819
error: generic parameters may not be used in const operations
29-
--> $DIR/type_const-on-generic-expr.rs:27:47
20+
--> $DIR/type_const-on-generic-expr.rs:28:47
3021
|
3122
LL | const N2<const I: usize>: usize = const { I + 1 };
32-
| ^ cannot perform const operation using `I`
33-
|
34-
= help: const parameters may only be used as standalone arguments here, i.e. `I`
35-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
23+
| ^
3624

3725
error: generic parameters may not be used in const operations
38-
--> $DIR/type_const-on-generic-expr.rs:30:35
26+
--> $DIR/type_const-on-generic-expr.rs:31:35
3927
|
4028
LL | const N3: usize = const { 2 & X };
41-
| ^ cannot perform const operation using `X`
29+
| ^
30+
31+
error: generic parameters may not be used in const operations
32+
--> $DIR/type_const-on-generic-expr.rs:5:53
33+
|
34+
LL | const FREE1<T>: usize = const { std::mem::size_of::<T>() };
35+
| ^
4236
|
43-
= help: const parameters may only be used as standalone arguments here, i.e. `X`
44-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
37+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
4538

46-
error: aborting due to 5 previous errors
39+
error: aborting due to 6 previous errors
4740

0 commit comments

Comments
 (0)