Skip to content

Commit f9944a9

Browse files
authored
Rollup merge of #103319 - fee1-dead-contrib:improve_tilde_const_msg, r=oli-obk
Improve "`~const` is not allowed here" message r? `@oli-obk`
2 parents 801e326 + ebf5028 commit f9944a9

File tree

6 files changed

+85
-25
lines changed

6 files changed

+85
-25
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+43-20
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ enum SelfSemantic {
3838
No,
3939
}
4040

41+
/// What is the context that prevents using `~const`?
42+
enum DisallowTildeConstContext<'a> {
43+
TraitObject,
44+
ImplTrait,
45+
Fn(FnKind<'a>),
46+
}
47+
4148
struct AstValidator<'a> {
4249
session: &'a Session,
4350

@@ -56,7 +63,7 @@ struct AstValidator<'a> {
5663
/// e.g., `impl Iterator<Item = impl Debug>`.
5764
outer_impl_trait: Option<Span>,
5865

59-
is_tilde_const_allowed: bool,
66+
disallow_tilde_const: Option<DisallowTildeConstContext<'a>>,
6067

6168
/// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
6269
/// or `Foo::Bar<impl Trait>`
@@ -93,18 +100,26 @@ impl<'a> AstValidator<'a> {
93100
self.is_impl_trait_banned = old;
94101
}
95102

96-
fn with_tilde_const(&mut self, allowed: bool, f: impl FnOnce(&mut Self)) {
97-
let old = mem::replace(&mut self.is_tilde_const_allowed, allowed);
103+
fn with_tilde_const(
104+
&mut self,
105+
disallowed: Option<DisallowTildeConstContext<'a>>,
106+
f: impl FnOnce(&mut Self),
107+
) {
108+
let old = mem::replace(&mut self.disallow_tilde_const, disallowed);
98109
f(self);
99-
self.is_tilde_const_allowed = old;
110+
self.disallow_tilde_const = old;
100111
}
101112

102113
fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
103-
self.with_tilde_const(true, f)
114+
self.with_tilde_const(None, f)
104115
}
105116

106-
fn with_banned_tilde_const(&mut self, f: impl FnOnce(&mut Self)) {
107-
self.with_tilde_const(false, f)
117+
fn with_banned_tilde_const(
118+
&mut self,
119+
ctx: DisallowTildeConstContext<'a>,
120+
f: impl FnOnce(&mut Self),
121+
) {
122+
self.with_tilde_const(Some(ctx), f)
108123
}
109124

110125
fn with_let_management(
@@ -172,7 +187,7 @@ impl<'a> AstValidator<'a> {
172187
fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
173188
let old = mem::replace(&mut self.outer_impl_trait, outer);
174189
if outer.is_some() {
175-
self.with_banned_tilde_const(f);
190+
self.with_banned_tilde_const(DisallowTildeConstContext::ImplTrait, f);
176191
} else {
177192
f(self);
178193
}
@@ -197,7 +212,10 @@ impl<'a> AstValidator<'a> {
197212
TyKind::ImplTrait(..) => {
198213
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
199214
}
200-
TyKind::TraitObject(..) => self.with_banned_tilde_const(|this| visit::walk_ty(this, t)),
215+
TyKind::TraitObject(..) => self
216+
.with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| {
217+
visit::walk_ty(this, t)
218+
}),
201219
TyKind::Path(ref qself, ref path) => {
202220
// We allow these:
203221
// - `Option<impl Trait>`
@@ -1411,13 +1429,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14111429
);
14121430
err.emit();
14131431
}
1414-
(_, TraitBoundModifier::MaybeConst) => {
1415-
if !self.is_tilde_const_allowed {
1416-
self.err_handler()
1417-
.struct_span_err(bound.span(), "`~const` is not allowed here")
1418-
.note("only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions")
1419-
.emit();
1420-
}
1432+
(_, TraitBoundModifier::MaybeConst) if let Some(reason) = &self.disallow_tilde_const => {
1433+
let mut err = self.err_handler().struct_span_err(bound.span(), "`~const` is not allowed here");
1434+
match reason {
1435+
DisallowTildeConstContext::TraitObject => err.note("trait objects cannot have `~const` trait bounds"),
1436+
DisallowTildeConstContext::ImplTrait => err.note("`impl Trait`s cannot have `~const` trait bounds"),
1437+
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => err.note("closures cannot have `~const` trait bounds"),
1438+
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => err.span_note(ident.span, "this function is not `const`, so it cannot have `~const` trait bounds"),
1439+
};
1440+
err.emit();
14211441
}
14221442
(_, TraitBoundModifier::MaybeConstMaybe) => {
14231443
self.err_handler()
@@ -1523,10 +1543,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
15231543
});
15241544
}
15251545

1526-
let tilde_const_allowed = matches!(fk.header(), Some(FnHeader { .. }))
1527-
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
1546+
let tilde_const_allowed =
1547+
matches!(fk.header(), Some(FnHeader { constness: ast::Const::Yes(_), .. }))
1548+
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
1549+
1550+
let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
15281551

1529-
self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk));
1552+
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
15301553
}
15311554

15321555
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
@@ -1770,7 +1793,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
17701793
in_const_trait_impl: false,
17711794
has_proc_macro_decls: false,
17721795
outer_impl_trait: None,
1773-
is_tilde_const_allowed: false,
1796+
disallow_tilde_const: None,
17741797
is_impl_trait_banned: false,
17751798
is_assoc_ty_bound_banned: false,
17761799
forbidden_let_reason: Some(ForbiddenLetReason::GenericForbidden),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(const_trait_impl)]
2+
3+
#[const_trait]
4+
trait Bar {}
5+
6+
fn foo<T>() where T: ~const Bar {}
7+
//~^ ERROR `~const` is not allowed
8+
9+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: `~const` is not allowed here
2+
--> $DIR/issue-90052.rs:6:22
3+
|
4+
LL | fn foo<T>() where T: ~const Bar {}
5+
| ^^^^^^^^^^
6+
|
7+
note: this function is not `const`, so it cannot have `~const` trait bounds
8+
--> $DIR/issue-90052.rs:6:4
9+
|
10+
LL | fn foo<T>() where T: ~const Bar {}
11+
| ^^^
12+
13+
error: aborting due to previous error
14+

src/test/ui/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// check-pass
21
#![feature(const_trait_impl)]
32
#![feature(generic_arg_infer)]
43
#![feature(generic_const_exprs)]
@@ -24,6 +23,7 @@ impl const Add42 for () {
2423
}
2524

2625
fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
26+
//~^ ERROR `~const` is not allowed here
2727
Foo
2828
}
2929

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: `~const` is not allowed here
2+
--> $DIR/tilde-const-and-const-params.rs:25:11
3+
|
4+
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
5+
| ^^^^^^^^^^^^
6+
|
7+
note: this function is not `const`, so it cannot have `~const` trait bounds
8+
--> $DIR/tilde-const-and-const-params.rs:25:4
9+
|
10+
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
11+
| ^^^
12+
13+
error: aborting due to previous error
14+

src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,31 @@ error: `~const` is not allowed here
44
LL | fn rpit() -> impl ~const T { S }
55
| ^^^^^^^^
66
|
7-
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
7+
= note: `impl Trait`s cannot have `~const` trait bounds
88

99
error: `~const` is not allowed here
1010
--> $DIR/tilde-const-invalid-places.rs:12:17
1111
|
1212
LL | fn apit(_: impl ~const T) {}
1313
| ^^^^^^^^
1414
|
15-
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
15+
= note: `impl Trait`s cannot have `~const` trait bounds
1616

1717
error: `~const` is not allowed here
1818
--> $DIR/tilde-const-invalid-places.rs:15:50
1919
|
2020
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
2121
| ^^^^^^^^
2222
|
23-
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
23+
= note: `impl Trait`s cannot have `~const` trait bounds
2424

2525
error: `~const` is not allowed here
2626
--> $DIR/tilde-const-invalid-places.rs:18:48
2727
|
2828
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
2929
| ^^^^^^^^
3030
|
31-
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
31+
= note: `impl Trait`s cannot have `~const` trait bounds
3232

3333
error: `~const` and `?` are mutually exclusive
3434
--> $DIR/tilde-const-invalid-places.rs:21:25

0 commit comments

Comments
 (0)