From 193df11c1482cf42f7e4dd6c45b12cde7c7978d5 Mon Sep 17 00:00:00 2001 From: Luca Versari Date: Mon, 16 Sep 2024 11:56:22 +0200 Subject: [PATCH] Fix ICE when passing DefId-creating args to legacy_const_generics. --- compiler/rustc_ast_lowering/messages.ftl | 2 + compiler/rustc_ast_lowering/src/errors.rs | 7 +++ compiler/rustc_ast_lowering/src/expr.rs | 44 ++++++++++++++++++- tests/crashes/123077-2.rs | 12 ----- tests/crashes/129150.rs | 7 --- ...ustc_legacy_const_generics-issue-123077.rs | 20 +++++++++ ..._legacy_const_generics-issue-123077.stderr | 26 +++++++++++ 7 files changed, 97 insertions(+), 21 deletions(-) delete mode 100644 tests/crashes/123077-2.rs delete mode 100644 tests/crashes/129150.rs create mode 100644 tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.rs create mode 100644 tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index a5ee6713be8ed..57e283340b7e5 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -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} diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 6b39c2d39556c..7a2138c6698bf 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -451,3 +451,10 @@ pub(crate) struct YieldInClosure { #[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")] pub suggestion: Option, } + +#[derive(Diagnostic)] +#[diag(ast_lowering_invalid_legacy_const_generic_arg)] +pub(crate) struct InvalidLegacyConstGenericArg { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index e105026ebd19d..4e0d5764aca39 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1,4 +1,5 @@ use std::assert_matches::assert_matches; +use std::ops::ControlFlow; use rustc_ast::ptr::P as AstP; use rustc_ast::*; @@ -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, @@ -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; + + 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]) -> &'hir [hir::Expr<'hir>] { self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x))) @@ -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); diff --git a/tests/crashes/123077-2.rs b/tests/crashes/123077-2.rs deleted file mode 100644 index e086e330337ab..0000000000000 --- a/tests/crashes/123077-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #123077 -//@ only-x86_64 -use std::arch::x86_64::{__m128, _mm_blend_ps}; - -pub fn sse41_blend_noinline( ) -> __m128 { - let f = { |x, y| unsafe { - _mm_blend_ps(x, y, { |x, y| unsafe }) - }}; - f(x, y) -} - -pub fn main() {} diff --git a/tests/crashes/129150.rs b/tests/crashes/129150.rs deleted file mode 100644 index 9f8c2ba173939..0000000000000 --- a/tests/crashes/129150.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: rust-lang/rust#129150 -//@ only-x86_64 -use std::arch::x86_64::_mm_blend_ps; - -pub fn main() { - _mm_blend_ps(1, 2, &const {} ); -} diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.rs b/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.rs new file mode 100644 index 0000000000000..6d77f05e7061d --- /dev/null +++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.rs @@ -0,0 +1,20 @@ +const fn foo() -> 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 + + std::arch::x86_64::_mm_blend_ps(1, 2, &const {}); + //~^ invalid argument to a legacy const generic +} diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr b/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr new file mode 100644 index 0000000000000..7032adba0ba49 --- /dev/null +++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-issue-123077.stderr @@ -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 +