Skip to content

Commit 34d5e7d

Browse files
committed
mgca always resolve params
1 parent ce63e5d commit 34d5e7d

File tree

8 files changed

+133
-92
lines changed

8 files changed

+133
-92
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
@@ -116,6 +116,13 @@ fn typeck_with_inspect<'tcx>(
116116
return tcx.typeck(typeck_root_def_id);
117117
}
118118

119+
if let DefKind::AnonConst = tcx.def_kind(def_id)
120+
&& let ty::AnonConstKind::MCG = tcx.anon_const_kind(def_id)
121+
&& let Err(e) = tcx.hir_const_arg_anon_check_invalid_param_uses(def_id)
122+
{
123+
e.raise_fatal();
124+
}
125+
119126
let id = tcx.local_def_id_to_hir_id(def_id);
120127
let node = tcx.hir_node(id);
121128
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;
@@ -1086,6 +1088,47 @@ impl<'tcx> TyCtxt<'tcx> {
10861088

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

10911134
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
@@ -4842,12 +4842,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
48424842
constant, anon_const_kind
48434843
);
48444844

4845-
let is_trivial_const_arg = if self.r.tcx.features().min_generic_const_args() {
4846-
matches!(constant.mgca_disambiguation, MgcaDisambiguation::Direct)
4847-
} else {
4848-
constant.value.is_potential_trivial_const_arg()
4849-
};
4850-
4845+
let is_trivial_const_arg = constant.value.is_potential_trivial_const_arg();
48514846
self.resolve_anon_const_manual(is_trivial_const_arg, anon_const_kind, |this| {
48524847
this.resolve_expr(&constant.value, None)
48534848
})
@@ -4877,7 +4872,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
48774872
AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes,
48784873
AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
48794874
AnonConstKind::ConstArg(_) => {
4880-
if self.r.tcx.features().generic_const_exprs() || is_trivial_const_arg {
4875+
if self.r.tcx.features().generic_const_exprs()
4876+
|| self.r.tcx.features().min_generic_const_args()
4877+
|| is_trivial_const_arg
4878+
{
48814879
ConstantHasGenerics::Yes
48824880
} else {
48834881
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 }>;
Lines changed: 51 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,82 @@
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-
46-
error: generic parameters may not be used in const operations
47-
--> $DIR/explicit_anon_consts.rs:64:58
48-
|
49-
LL | struct Default3<const N: usize, const M: usize = const { N }>;
50-
| ^ cannot perform const operation using `N`
51-
|
52-
= help: const parameters may only be used as standalone arguments here, i.e. `N`
53-
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
54-
551
error: complex const arguments must be placed inside of a `const` block
56-
--> $DIR/explicit_anon_consts.rs:10:33
2+
--> $DIR/explicit_anon_consts.rs:11:33
573
|
584
LL | type Adt4<const N: usize> = Foo<{ 1 + 1 }>;
595
| ^^^^^^^^^
606

617
error: complex const arguments must be placed inside of a `const` block
62-
--> $DIR/explicit_anon_consts.rs:18:34
8+
--> $DIR/explicit_anon_consts.rs:19:34
639
|
6410
LL | type Arr4<const N: usize> = [(); 1 + 1];
6511
| ^^^^^
6612

6713
error: complex const arguments must be placed inside of a `const` block
68-
--> $DIR/explicit_anon_consts.rs:27:19
14+
--> $DIR/explicit_anon_consts.rs:28:19
6915
|
7016
LL | let _4 = [(); 1 + 1];
7117
| ^^^^^
7218

7319
error: complex const arguments must be placed inside of a `const` block
74-
--> $DIR/explicit_anon_consts.rs:40:38
20+
--> $DIR/explicit_anon_consts.rs:41:38
7521
|
7622
LL | const ITEM4<const N: usize>: usize = { 1 + 1 };
7723
| ^^^^^^^^^
7824

7925
error: complex const arguments must be placed inside of a `const` block
80-
--> $DIR/explicit_anon_consts.rs:57:23
26+
--> $DIR/explicit_anon_consts.rs:58:23
8127
|
8228
LL | T4: Trait<ASSOC = { 1 + 1 }>,
8329
| ^^^^^^^^^
8430

8531
error: complex const arguments must be placed inside of a `const` block
86-
--> $DIR/explicit_anon_consts.rs:66:50
32+
--> $DIR/explicit_anon_consts.rs:67:50
8733
|
8834
LL | struct Default4<const N: usize, const M: usize = { 1 + 1 }>;
8935
| ^^^^^^^^^
9036

91-
error: aborting due to 12 previous errors
37+
error: generic parameters may not be used in const operations
38+
--> $DIR/explicit_anon_consts.rs:8:41
39+
|
40+
LL | type Adt3<const N: usize> = Foo<const { N }>;
41+
| ^
42+
43+
error: generic parameters may not be used in const operations
44+
--> $DIR/explicit_anon_consts.rs:17:42
45+
|
46+
LL | type Arr3<const N: usize> = [(); const { N }];
47+
| ^
48+
49+
error: generic parameters may not be used in const operations
50+
--> $DIR/explicit_anon_consts.rs:38:46
51+
|
52+
LL | const ITEM3<const N: usize>: usize = const { N };
53+
| ^
54+
55+
error: generic parameters may not be used in const operations
56+
--> $DIR/explicit_anon_consts.rs:56:31
57+
|
58+
LL | T3: Trait<ASSOC = const { N }>,
59+
| ^
60+
61+
error: generic parameters may not be used in const operations
62+
--> $DIR/explicit_anon_consts.rs:65:58
63+
|
64+
LL | struct Default3<const N: usize, const M: usize = const { N }>;
65+
| ^
66+
67+
error: generic parameters may not be used in const operations
68+
--> $DIR/explicit_anon_consts.rs:26:27
69+
|
70+
LL | let _3 = [(); const { N }];
71+
| ^
72+
73+
error: generic parameters may not be used in const operations
74+
--> $DIR/explicit_anon_consts.rs:8:41
75+
|
76+
LL | type Adt3<const N: usize> = Foo<const { N }>;
77+
| ^
78+
|
79+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
80+
81+
error: aborting due to 13 previous errors
9282

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)