Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use super::{
use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure};
use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope};

struct WillCreateDefIdsVisitor {}
pub(super) struct WillCreateDefIdsVisitor;

impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor {
type Result = ControlFlow<Span>;
Expand Down Expand Up @@ -479,18 +479,18 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
DefPathData::LateAnonConst,
f.span,
);
let mut visitor = WillCreateDefIdsVisitor {};
let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) {
Box::new(Expr {
id: self.next_node_id(),
kind: ExprKind::Err(invalid_expr_error(self.tcx, span)),
span: f.span,
attrs: [].into(),
tokens: None,
})
} else {
arg
};
let const_value =
if let ControlFlow::Break(span) = WillCreateDefIdsVisitor.visit_expr(&arg) {
Box::new(Expr {
id: self.next_node_id(),
kind: ExprKind::Err(invalid_expr_error(self.tcx, span)),
span: f.span,
attrs: [].into(),
tokens: None,
})
} else {
arg
};

let anon_const = AnonConst {
id: node_id,
Expand Down
13 changes: 8 additions & 5 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use std::mem;
use std::sync::Arc;

use rustc_ast::node_id::NodeMap;
use rustc_ast::visit::Visitor;
use rustc_ast::{self as ast, *};
use rustc_attr_parsing::{AttributeParser, Late, OmitDoc};
use rustc_data_structures::fingerprint::Fingerprint;
Expand Down Expand Up @@ -2563,12 +2564,14 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
let span = self.lower_span(expr.span);

let overly_complex_const = |this: &mut Self| {
let e = this.dcx().struct_span_err(
expr.span,
"complex const arguments must be placed inside of a `const` block",
);
let msg = "complex const arguments must be placed inside of a `const` block";
let e = if expr::WillCreateDefIdsVisitor.visit_expr(expr).is_break() {
this.dcx().struct_span_fatal(expr.span, msg).emit()
} else {
this.dcx().struct_span_err(expr.span, msg).emit()
};

ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(e.emit()), span }
ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(e), span }
};

match &expr.kind {
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/const-generics/mgca/array-expr-complex.r1.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: complex const arguments must be placed inside of a `const` block
--> $DIR/array-expr-complex.rs:11:28
|
LL | takes_array::<{ [1, 2, 1 + 2] }>();
| ^^^^^

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/const-generics/mgca/array-expr-complex.r2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: complex const arguments must be placed inside of a `const` block
--> $DIR/array-expr-complex.rs:14:21
|
LL | takes_array::<{ [X; 3] }>();
| ^^^^^^

error: aborting due to 1 previous error

8 changes: 8 additions & 0 deletions tests/ui/const-generics/mgca/array-expr-complex.r3.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: complex const arguments must be placed inside of a `const` block
--> $DIR/array-expr-complex.rs:17:21
|
LL | takes_array::<{ [0; Y] }>();
| ^^^^^^

error: aborting due to 1 previous error

11 changes: 8 additions & 3 deletions tests/ui/const-generics/mgca/array-expr-complex.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
//@ revisions: r1 r2 r3

#![expect(incomplete_features)]
#![feature(min_generic_const_args, adt_const_params)]

fn takes_array<const A: [u32; 3]>() {}

fn generic_caller<const X: u32, const Y: usize>() {
// not supported yet
#[cfg(r1)]
takes_array::<{ [1, 2, 1 + 2] }>();
//~^ ERROR: complex const arguments must be placed inside of a `const` block
//[r1]~^ ERROR: complex const arguments must be placed inside of a `const` block
#[cfg(r2)]
takes_array::<{ [X; 3] }>();
//~^ ERROR: complex const arguments must be placed inside of a `const` block
//[r2]~^ ERROR: complex const arguments must be placed inside of a `const` block
#[cfg(r3)]
takes_array::<{ [0; Y] }>();
//~^ ERROR: complex const arguments must be placed inside of a `const` block
//[r3]~^ ERROR: complex const arguments must be placed inside of a `const` block
}

fn main() {}
20 changes: 0 additions & 20 deletions tests/ui/const-generics/mgca/array-expr-complex.stderr

This file was deleted.

12 changes: 12 additions & 0 deletions tests/ui/const-generics/mgca/bad-const-arg-fn-154539.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(min_generic_const_args)]

trait Iter<
const FN: fn() = {
|| { //~ ERROR complex const arguments must be placed inside of a `const` block
use std::io::*;
write!(_, "")
}
},
>
{
}
11 changes: 11 additions & 0 deletions tests/ui/const-generics/mgca/bad-const-arg-fn-154539.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: complex const arguments must be placed inside of a `const` block
--> $DIR/bad-const-arg-fn-154539.rs:5:9
|
LL | / || {
LL | | use std::io::*;
LL | | write!(_, "")
LL | | }
| |_________^

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0428]: the name `foo` is defined multiple times
--> $DIR/hir-crate-items-before-lowering-ices.rs:13:17
|
LL | fn foo() {}
| -------- previous definition of the value `foo` here
LL | reuse foo;
| ^^^^^^^^^^ `foo` redefined here
|
= note: `foo` must be defined only once in the value namespace of this block

error: complex const arguments must be placed inside of a `const` block
--> $DIR/hir-crate-items-before-lowering-ices.rs:11:13
|
LL | / {
LL | | fn foo() {}
LL | | reuse foo;
LL | | 2
LL | | },
| |_____________^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0428`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error: `#[deprecated]` attribute cannot be used on delegations
--> $DIR/hir-crate-items-before-lowering-ices.rs:27:9
|
LL | #[deprecated]
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements
= note: `#[deny(useless_deprecated)]` on by default

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/hir-crate-items-before-lowering-ices.rs:37:11
|
LL | reuse a as b {
| ___________^______-
LL | | fn foo<T>() {};
LL | | foo
LL | | }
| |_____- unexpected argument of type `fn() {foo::<_>}`
|
note: function defined here
--> $DIR/hir-crate-items-before-lowering-ices.rs:35:8
|
LL | fn a() {}
| ^
help: remove the extra argument
|
LL - reuse a as b {
LL + reuse {
|

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0061`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: complex const arguments must be placed inside of a `const` block
--> $DIR/hir-crate-items-before-lowering-ices.rs:47:13
|
LL | / {
LL | |
LL | | struct W<I>;
LL | | impl<I> W<I> {
... |
LL | | },
| |_____________^

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0425]: cannot find value `async` in this scope
--> $DIR/hir-crate-items-before-lowering-ices.rs:66:13
|
LL | async || {};
| ^^^^^ not found in this scope

error[E0308]: mismatched types
--> $DIR/hir-crate-items-before-lowering-ices.rs:66:22
|
LL | async || {};
| ^^ expected `bool`, found `()`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0308, E0425.
For more information about an error, try `rustc --explain E0308`.
24 changes: 15 additions & 9 deletions tests/ui/delegation/hir-crate-items-before-lowering-ices.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
//@ revisions: ice_155125 ice_155127 ice_155128 ice_155164 ice_155202

#![feature(min_generic_const_args, fn_delegation)]
#![allow(incomplete_features)]

#[cfg(ice_155125)]
mod ice_155125 {
struct S<const N: usize>;
impl
S<
{ //~ ERROR: complex const arguments must be placed inside of a `const` block
{ //[ice_155125]~ ERROR: complex const arguments must be placed inside of a `const` block
fn foo() {}
reuse foo; //~ ERROR: the name `foo` is defined multiple times
reuse foo; //[ice_155125]~ ERROR: the name `foo` is defined multiple times
2
},
>
{
}
}

#[cfg(ice_155127)]
mod ice_155127 {
struct S;

fn foo() {}
impl S {
#[deprecated] //~ ERROR: `#[deprecated]` attribute cannot be used on delegations
//~^ WARN: this was previously accepted by the compiler but is being phased out;
#[deprecated] //[ice_155127]~ ERROR: `#[deprecated]` attribute cannot be used on delegations
//[ice_155127]~^ WARN: this was previously accepted by the compiler but is being phased out;
reuse foo;
}
}

#[cfg(ice_155128)]
mod ice_155128 {
fn a() {}

reuse a as b { //~ ERROR: this function takes 0 arguments but 1 argument was supplied
reuse a as b { //[ice_155128]~ ERROR: this function takes 0 arguments but 1 argument was supplied
fn foo<T>() {};
foo
}
}

#[cfg(ice_155164)]
mod ice_155164 {
struct X<const N: usize, F> {
inner: std::iter::Map<
{
//~^ ERROR: complex const arguments must be placed inside of a `const` block
//~| ERROR: constant provided when a type was expected
//[ice_155164]~^ ERROR: complex const arguments must be placed inside of a `const` block
struct W<I>;
impl<I> W<I> {
reuse Iterator::fold;
Expand All @@ -51,14 +56,15 @@ mod ice_155164 {
}
}

#[cfg(ice_155202)]
mod ice_155202 {
trait Trait {
fn bar(self);
}
impl Trait for () {
reuse Trait::bar {
async || {}; //~ ERROR: mismatched types
//~^ ERROR: cannot find value `async` in this scope
async || {}; //[ice_155202]~ ERROR: mismatched types
//[ice_155202]~^ ERROR: cannot find value `async` in this scope
}
}
}
Expand Down
Loading
Loading