Skip to content

Commit 442617c

Browse files
committed
misc nameres changes for anon consts
1 parent 4a18324 commit 442617c

File tree

7 files changed

+202
-133
lines changed

7 files changed

+202
-133
lines changed

compiler/rustc_ast/src/ast.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ impl Path {
120120
pub fn is_global(&self) -> bool {
121121
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
122122
}
123+
124+
/// If this path is a single identifier with no arguments, does not ensure
125+
/// that the path resolves to a const param, the caller should check this.
126+
pub fn is_potential_trivial_const_arg(&self) -> bool {
127+
self.segments.len() == 1 && self.segments[0].args.is_none()
128+
}
123129
}
124130

125131
/// A segment of a path: an identifier, an optional lifetime, and a set of types.
@@ -1154,7 +1160,9 @@ impl Expr {
11541160
///
11551161
/// If this is not the case, name resolution does not resolve `N` when using
11561162
/// `min_const_generics` as more complex expressions are not supported.
1157-
pub fn is_potential_trivial_const_param(&self) -> bool {
1163+
///
1164+
/// Does not ensure that the path resolves to a const param, the caller should check this.
1165+
pub fn is_potential_trivial_const_arg(&self) -> bool {
11581166
let this = if let ExprKind::Block(block, None) = &self.kind
11591167
&& block.stmts.len() == 1
11601168
&& let StmtKind::Expr(expr) = &block.stmts[0].kind
@@ -1165,8 +1173,7 @@ impl Expr {
11651173
};
11661174

11671175
if let ExprKind::Path(None, path) = &this.kind
1168-
&& path.segments.len() == 1
1169-
&& path.segments[0].args.is_none()
1176+
&& path.is_potential_trivial_const_arg()
11701177
{
11711178
true
11721179
} else {

compiler/rustc_ast/src/visit.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ pub trait Visitor<'ast>: Sized {
188188
fn visit_variant(&mut self, v: &'ast Variant) {
189189
walk_variant(self, v)
190190
}
191+
fn visit_variant_discr(&mut self, discr: &'ast AnonConst) {
192+
self.visit_anon_const(discr);
193+
}
191194
fn visit_label(&mut self, label: &'ast Label) {
192195
walk_label(self, label)
193196
}
@@ -380,7 +383,7 @@ where
380383
visitor.visit_ident(variant.ident);
381384
visitor.visit_vis(&variant.vis);
382385
visitor.visit_variant_data(&variant.data);
383-
walk_list!(visitor, visit_anon_const, &variant.disr_expr);
386+
walk_list!(visitor, visit_variant_discr, &variant.disr_expr);
384387
walk_list!(visitor, visit_attribute, &variant.attrs);
385388
}
386389

compiler/rustc_ast_lowering/src/lib.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1190,13 +1190,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11901190
// parsing. We try to resolve that ambiguity by attempting resolution in both the
11911191
// type and value namespaces. If we resolved the path in the value namespace, we
11921192
// transform it into a generic const argument.
1193-
TyKind::Path(qself, path) => {
1193+
TyKind::Path(None, path) => {
11941194
if let Some(res) = self
11951195
.resolver
11961196
.get_partial_res(ty.id)
11971197
.and_then(|partial_res| partial_res.full_res())
11981198
{
1199-
if !res.matches_ns(Namespace::TypeNS) {
1199+
if !res.matches_ns(Namespace::TypeNS)
1200+
&& path.is_potential_trivial_const_arg()
1201+
{
12001202
debug!(
12011203
"lower_generic_arg: Lowering type argument as const argument: {:?}",
12021204
ty,
@@ -1218,7 +1220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12181220

12191221
let path_expr = Expr {
12201222
id: ty.id,
1221-
kind: ExprKind::Path(qself.clone(), path.clone()),
1223+
kind: ExprKind::Path(None, path.clone()),
12221224
span,
12231225
attrs: AttrVec::new(),
12241226
tokens: None,

compiler/rustc_error_codes/src/error_codes/E0771.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
#### Note: this error code is no longer emitted by the compiler
2+
13
A non-`'static` lifetime was used in a const generic. This is currently not
24
allowed.
35

46
Erroneous code example:
57

6-
```compile_fail,E0771
8+
```compile_fail,E0770
79
#![feature(adt_const_params)]
810
911
fn function_with_str<'a, const STRING: &'a str>() {} // error!

compiler/rustc_hir_analysis/src/collect/generics_of.rs

+17-14
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,15 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
5151
// of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
5252
None
5353
} else if tcx.lazy_normalization() {
54-
if let Some(param_id) = tcx.hir().opt_const_param_default_param_def_id(hir_id) {
54+
let parent_node = tcx.hir().get_parent(hir_id);
55+
if let Node::Variant(Variant { disr_expr: Some(constant), .. }) = parent_node
56+
&& constant.hir_id == hir_id
57+
{
58+
// enum variant discriminants are not allowed to use any kind of generics
59+
None
60+
} else if let Some(param_id) =
61+
tcx.hir().opt_const_param_default_param_def_id(hir_id)
62+
{
5563
// If the def_id we are calling generics_of on is an anon ct default i.e:
5664
//
5765
// struct Foo<const N: usize = { .. }>;
@@ -94,15 +102,15 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
94102
has_self: generics.has_self,
95103
has_late_bound_regions: generics.has_late_bound_regions,
96104
};
105+
} else {
106+
// HACK(eddyb) this provides the correct generics when
107+
// `feature(generic_const_expressions)` is enabled, so that const expressions
108+
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
109+
//
110+
// Note that we do not supply the parent generics when using
111+
// `min_const_generics`.
112+
Some(parent_def_id.to_def_id())
97113
}
98-
99-
// HACK(eddyb) this provides the correct generics when
100-
// `feature(generic_const_expressions)` is enabled, so that const expressions
101-
// used with const generics, e.g. `Foo<{N+1}>`, can work at all.
102-
//
103-
// Note that we do not supply the parent generics when using
104-
// `min_const_generics`.
105-
Some(parent_def_id.to_def_id())
106114
} else {
107115
let parent_node = tcx.hir().get_parent(hir_id);
108116
match parent_node {
@@ -115,11 +123,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
115123
{
116124
Some(parent_def_id.to_def_id())
117125
}
118-
Node::Variant(Variant { disr_expr: Some(constant), .. })
119-
if constant.hir_id == hir_id =>
120-
{
121-
Some(parent_def_id.to_def_id())
122-
}
123126
Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => {
124127
Some(tcx.typeck_root_def_id(def_id.to_def_id()))
125128
}

compiler/rustc_resolve/src/ident.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -1188,11 +1188,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
11881188
}
11891189

11901190
RibKind::ConstantItem(trivial, _) => {
1191-
let features = self.tcx.sess.features_untracked();
1192-
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
1193-
if !(trivial == ConstantHasGenerics::Yes
1194-
|| features.generic_const_exprs)
1195-
{
1191+
if let ConstantHasGenerics::No(cause) = trivial {
11961192
// HACK(min_const_generics): If we encounter `Self` in an anonymous
11971193
// constant we can't easily tell if it's generic at this stage, so
11981194
// we instead remember this and then enforce the self type to be
@@ -1264,11 +1260,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12641260
| RibKind::ForwardGenericParamBan => continue,
12651261

12661262
RibKind::ConstantItem(trivial, _) => {
1267-
let features = self.tcx.sess.features_untracked();
1268-
// HACK(min_const_generics): We currently only allow `N` or `{ N }`.
1269-
if !(trivial == ConstantHasGenerics::Yes
1270-
|| features.generic_const_exprs)
1271-
{
1263+
if let ConstantHasGenerics::No(cause) = trivial {
12721264
if let Some(span) = finalize {
12731265
self.report_error(
12741266
span,

0 commit comments

Comments
 (0)