Skip to content

Commit a598998

Browse files
committed
Fix ICE when passing DefId-creating args to legacy_const_generics.
1 parent a5efa01 commit a598998

File tree

5 files changed

+61
-2
lines changed

5 files changed

+61
-2
lines changed

compiler/rustc_ast_lowering/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ ast_lowering_invalid_asm_template_modifier_reg_class =
103103
ast_lowering_invalid_asm_template_modifier_sym =
104104
asm template modifiers are not allowed for `sym` arguments
105105
106+
ast_lowering_invalid_legacy_const_generic_arg =
107+
invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
106108
ast_lowering_invalid_register =
107109
invalid register `{$reg}`: {$error}
108110

compiler/rustc_ast_lowering/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -451,3 +451,10 @@ pub(crate) struct YieldInClosure {
451451
#[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")]
452452
pub suggestion: Option<Span>,
453453
}
454+
455+
#[derive(Diagnostic)]
456+
#[diag(ast_lowering_invalid_legacy_const_generic_arg)]
457+
pub(crate) struct InvalidLegacyConstGenericArg {
458+
#[primary_span]
459+
pub span: Span,
460+
}

compiler/rustc_ast_lowering/src/expr.rs

+40-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::assert_matches::assert_matches;
2+
use std::ops::ControlFlow;
23

34
use rustc_ast::ptr::P as AstP;
45
use rustc_ast::*;
@@ -12,6 +13,7 @@ use rustc_span::source_map::{respan, Spanned};
1213
use rustc_span::symbol::{kw, sym, Ident, Symbol};
1314
use rustc_span::{DesugaringKind, Span, DUMMY_SP};
1415
use thin_vec::{thin_vec, ThinVec};
16+
use visit::Visitor;
1517

1618
use super::errors::{
1719
AsyncCoroutinesNotSupported, AwaitOnlyInAsyncFnAndBlocks, BaseExpressionDoubleDot,
@@ -22,9 +24,28 @@ use super::errors::{
2224
use super::{
2325
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
2426
};
25-
use crate::errors::YieldInClosure;
27+
use crate::errors::{InvalidLegacyConstGenericArg, YieldInClosure};
2628
use crate::{fluent_generated, FnDeclKind, ImplTraitPosition};
2729

30+
struct WillCreateDefIdsVisitor {}
31+
32+
impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor {
33+
type Result = ControlFlow<()>;
34+
35+
fn visit_item(&mut self, _: &'v Item) -> Self::Result {
36+
ControlFlow::Break(())
37+
}
38+
39+
fn visit_expr(&mut self, ex: &'v Expr) -> Self::Result {
40+
match ex.kind {
41+
ExprKind::Gen(..) | ExprKind::ConstBlock(..) | ExprKind::Closure(..) => {
42+
ControlFlow::Break(())
43+
}
44+
_ => ControlFlow::Continue(()),
45+
}
46+
}
47+
}
48+
2849
impl<'hir> LoweringContext<'_, 'hir> {
2950
fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
3051
self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x)))
@@ -392,7 +413,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
392413
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
393414
}
394415

395-
let anon_const = AnonConst { id: node_id, value: arg };
416+
let mut visitor = WillCreateDefIdsVisitor {};
417+
let const_value = if visitor.visit_expr(&arg).is_break() {
418+
AstP(Expr {
419+
id: self.next_node_id(),
420+
kind: ExprKind::Err(
421+
self.tcx
422+
.dcx()
423+
.emit_err(InvalidLegacyConstGenericArg { span: arg.span }),
424+
),
425+
span: f.span,
426+
attrs: [].into(),
427+
tokens: None,
428+
})
429+
} else {
430+
arg
431+
};
432+
433+
let anon_const = AnonConst { id: node_id, value: const_value };
396434
generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
397435
} else {
398436
real_args.push(arg);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, || ());
3+
//~^ invalid argument to a legacy const generic
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
2+
--> $DIR/invalid-rustc_legacy_const_generics-issue-123077.rs:2:55
3+
|
4+
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, || ());
5+
| ^^^^^
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)