Skip to content

Commit

Permalink
Fix ICE when passing DefId-creating args to legacy_const_generics.
Browse files Browse the repository at this point in the history
  • Loading branch information
veluca93 committed Sep 16, 2024
1 parent a5efa01 commit 77a3a5e
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 2 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_ast_lowering/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ ast_lowering_invalid_asm_template_modifier_reg_class =
ast_lowering_invalid_asm_template_modifier_sym =
asm template modifiers are not allowed for `sym` arguments
ast_lowering_invalid_legacy_const_generic_arg =
invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
ast_lowering_invalid_register =
invalid register `{$reg}`: {$error}
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_ast_lowering/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,3 +451,10 @@ pub(crate) struct YieldInClosure {
#[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")]
pub suggestion: Option<Span>,
}

#[derive(Diagnostic)]
#[diag(ast_lowering_invalid_legacy_const_generic_arg)]
pub(crate) struct InvalidLegacyConstGenericArg {
#[primary_span]
pub span: Span,
}
44 changes: 42 additions & 2 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::assert_matches::assert_matches;
use std::ops::ControlFlow;

use rustc_ast::ptr::P as AstP;
use rustc_ast::*;
Expand All @@ -12,6 +13,7 @@ use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{DesugaringKind, Span, DUMMY_SP};
use thin_vec::{thin_vec, ThinVec};
use visit::{walk_expr, Visitor};

use super::errors::{
AsyncCoroutinesNotSupported, AwaitOnlyInAsyncFnAndBlocks, BaseExpressionDoubleDot,
Expand All @@ -22,9 +24,32 @@ use super::errors::{
use super::{
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
};
use crate::errors::YieldInClosure;
use crate::errors::{InvalidLegacyConstGenericArg, YieldInClosure};
use crate::{fluent_generated, FnDeclKind, ImplTraitPosition};

struct WillCreateDefIdsVisitor {}

impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor {
type Result = ControlFlow<Span>;

fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
ControlFlow::Break(c.value.span)
}

fn visit_item(&mut self, item: &'v Item) -> Self::Result {
ControlFlow::Break(item.span)
}

fn visit_expr(&mut self, ex: &'v Expr) -> Self::Result {
match ex.kind {
ExprKind::Gen(..) | ExprKind::ConstBlock(..) | ExprKind::Closure(..) => {
ControlFlow::Break(ex.span)
}
_ => walk_expr(self, ex),
}
}
}

impl<'hir> LoweringContext<'_, 'hir> {
fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x)))
Expand Down Expand Up @@ -392,7 +417,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
}

let anon_const = AnonConst { id: node_id, value: arg };
let mut visitor = WillCreateDefIdsVisitor {};
let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) {
AstP(Expr {
id: self.next_node_id(),
kind: ExprKind::Err(
self.tcx.dcx().emit_err(InvalidLegacyConstGenericArg { span }),
),
span: f.span,
attrs: [].into(),
tokens: None,
})
} else {
arg
};

let anon_const = AnonConst { id: node_id, value: const_value };
generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
} else {
real_args.push(arg);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const fn foo<const U: i32>() -> i32 {
U
}

fn main() {
std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, || ());
//~^ invalid argument to a legacy const generic

std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, 5 + || ());
//~^ invalid argument to a legacy const generic

std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<{ 1 + 2 }>());
//~^ invalid argument to a legacy const generic

std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<3>());
//~^ invalid argument to a legacy const generic
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
--> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:6:55
|
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, || ());
| ^^^^^

error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
--> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:9:59
|
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, 5 + || ());
| ^^^^^

error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
--> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:12:61
|
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<{ 1 + 2 }>());
| ^^^^^^^^^

error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
--> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:15:61
|
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<3>());
| ^

error: aborting due to 4 previous errors

0 comments on commit 77a3a5e

Please sign in to comment.