mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Fix ICE when passing DefId-creating args to legacy_const_generics.
This commit is contained in:
parent
ce40196577
commit
b462c68aee
@ -3270,6 +3270,7 @@ name = "rustc_ast_lowering"
|
|||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
|
"rustc_ast_pretty",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
"rustc_errors",
|
"rustc_errors",
|
||||||
"rustc_fluent_macro",
|
"rustc_fluent_macro",
|
||||||
|
@ -9,6 +9,7 @@ doctest = false
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
rustc_ast = { path = "../rustc_ast" }
|
rustc_ast = { path = "../rustc_ast" }
|
||||||
|
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
|
||||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||||
rustc_errors = { path = "../rustc_errors" }
|
rustc_errors = { path = "../rustc_errors" }
|
||||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||||
|
@ -103,6 +103,12 @@ ast_lowering_invalid_asm_template_modifier_reg_class =
|
|||||||
ast_lowering_invalid_asm_template_modifier_sym =
|
ast_lowering_invalid_asm_template_modifier_sym =
|
||||||
asm template modifiers are not allowed for `sym` arguments
|
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_legacy_const_generic_arg_suggestion =
|
||||||
|
try using a const generic argument instead
|
||||||
|
|
||||||
ast_lowering_invalid_register =
|
ast_lowering_invalid_register =
|
||||||
invalid register `{$reg}`: {$error}
|
invalid register `{$reg}`: {$error}
|
||||||
|
|
||||||
|
@ -451,3 +451,26 @@ pub(crate) struct YieldInClosure {
|
|||||||
#[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")]
|
#[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")]
|
||||||
pub suggestion: Option<Span>,
|
pub suggestion: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(ast_lowering_invalid_legacy_const_generic_arg)]
|
||||||
|
pub(crate) struct InvalidLegacyConstGenericArg {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub suggestion: UseConstGenericArg,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[multipart_suggestion(
|
||||||
|
ast_lowering_invalid_legacy_const_generic_arg_suggestion,
|
||||||
|
applicability = "maybe-incorrect"
|
||||||
|
)]
|
||||||
|
pub(crate) struct UseConstGenericArg {
|
||||||
|
#[suggestion_part(code = "::<{const_args}>")]
|
||||||
|
pub end_of_fn: Span,
|
||||||
|
pub const_args: String,
|
||||||
|
pub other_args: String,
|
||||||
|
#[suggestion_part(code = "{other_args}")]
|
||||||
|
pub call_args: Span,
|
||||||
|
}
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
use std::assert_matches::assert_matches;
|
use std::assert_matches::assert_matches;
|
||||||
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
use rustc_ast::ptr::P as AstP;
|
use rustc_ast::ptr::P as AstP;
|
||||||
use rustc_ast::*;
|
use rustc_ast::*;
|
||||||
|
use rustc_ast_pretty::pprust::expr_to_string;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::HirId;
|
use rustc_hir::HirId;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_session::errors::report_lit_error;
|
use rustc_session::errors::report_lit_error;
|
||||||
use rustc_span::source_map::{Spanned, respan};
|
use rustc_span::source_map::{Spanned, respan};
|
||||||
use rustc_span::symbol::{Ident, Symbol, kw, sym};
|
use rustc_span::symbol::{Ident, Symbol, kw, sym};
|
||||||
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
|
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
|
||||||
use thin_vec::{ThinVec, thin_vec};
|
use thin_vec::{ThinVec, thin_vec};
|
||||||
|
use visit::{Visitor, walk_expr};
|
||||||
|
|
||||||
use super::errors::{
|
use super::errors::{
|
||||||
AsyncCoroutinesNotSupported, AwaitOnlyInAsyncFnAndBlocks, BaseExpressionDoubleDot,
|
AsyncCoroutinesNotSupported, AwaitOnlyInAsyncFnAndBlocks, BaseExpressionDoubleDot,
|
||||||
@ -23,9 +27,32 @@ use super::errors::{
|
|||||||
use super::{
|
use super::{
|
||||||
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
|
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
|
||||||
};
|
};
|
||||||
use crate::errors::YieldInClosure;
|
use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure};
|
||||||
use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, fluent_generated};
|
use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, fluent_generated};
|
||||||
|
|
||||||
|
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> {
|
impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'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)))
|
self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x)))
|
||||||
@ -396,10 +423,34 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut error = None;
|
||||||
|
let mut invalid_expr_error = |tcx: TyCtxt<'_>, span| {
|
||||||
|
// Avoid emitting the error multiple times.
|
||||||
|
if error.is_none() {
|
||||||
|
let mut const_args = vec![];
|
||||||
|
let mut other_args = vec![];
|
||||||
|
for (idx, arg) in args.iter().enumerate() {
|
||||||
|
if legacy_args_idx.contains(&idx) {
|
||||||
|
const_args.push(format!("{{ {} }}", expr_to_string(arg)));
|
||||||
|
} else {
|
||||||
|
other_args.push(expr_to_string(arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let suggestion = UseConstGenericArg {
|
||||||
|
end_of_fn: f.span.shrink_to_hi(),
|
||||||
|
const_args: const_args.join(", "),
|
||||||
|
other_args: other_args.join(", "),
|
||||||
|
call_args: args[0].span.to(args.last().unwrap().span),
|
||||||
|
};
|
||||||
|
error = Some(tcx.dcx().emit_err(InvalidLegacyConstGenericArg { span, suggestion }));
|
||||||
|
}
|
||||||
|
error.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
// Split the arguments into const generics and normal arguments
|
// Split the arguments into const generics and normal arguments
|
||||||
let mut real_args = vec![];
|
let mut real_args = vec![];
|
||||||
let mut generic_args = ThinVec::new();
|
let mut generic_args = ThinVec::new();
|
||||||
for (idx, arg) in args.into_iter().enumerate() {
|
for (idx, arg) in args.iter().cloned().enumerate() {
|
||||||
if legacy_args_idx.contains(&idx) {
|
if legacy_args_idx.contains(&idx) {
|
||||||
let parent_def_id = self.current_def_id_parent;
|
let parent_def_id = self.current_def_id_parent;
|
||||||
let node_id = self.next_node_id();
|
let node_id = self.next_node_id();
|
||||||
@ -410,7 +461,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span);
|
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(invalid_expr_error(self.tcx, 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)));
|
generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const)));
|
||||||
} else {
|
} else {
|
||||||
real_args.push(arg);
|
real_args.push(arg);
|
||||||
|
@ -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() {}
|
|
@ -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 {} );
|
|
||||||
}
|
|
@ -0,0 +1,31 @@
|
|||||||
|
//@ only-x86_64
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, &const {});
|
||||||
|
//~^ invalid argument to a legacy const generic
|
||||||
|
|
||||||
|
std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, {
|
||||||
|
struct F();
|
||||||
|
//~^ invalid argument to a legacy const generic
|
||||||
|
1
|
||||||
|
});
|
||||||
|
|
||||||
|
std::arch::x86_64::_mm_inserti_si64(loop {}, loop {}, || (), 1 + || ());
|
||||||
|
//~^ invalid argument to a legacy const generic
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
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:8:55
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, || ());
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
help: try using a const generic argument instead
|
||||||
|
|
|
||||||
|
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:11:59
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, 5 + || ());
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
help: try using a const generic argument instead
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_blend_ps::<{ 5 + (|| ()) }>(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:14:61
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<{ 1 + 2 }>());
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: try using a const generic argument instead
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_blend_ps::<{ foo::<{ 1 + 2 }>() }>(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:17:61
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, foo::<3>());
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
help: try using a const generic argument instead
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_blend_ps::<{ foo::<3>() }>(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:20:56
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_blend_ps(loop {}, loop {}, &const {});
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
help: try using a const generic argument instead
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_blend_ps::<{ &const {} }>(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:24:9
|
||||||
|
|
|
||||||
|
LL | struct F();
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: try using a const generic argument instead
|
||||||
|
|
|
||||||
|
LL ~ std::arch::x86_64::_mm_blend_ps::<{ {
|
||||||
|
LL + struct F();
|
||||||
|
LL + 1
|
||||||
|
LL ~ } }>(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:29:59
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_inserti_si64(loop {}, loop {}, || (), 1 + || ());
|
||||||
|
| ^^^^^
|
||||||
|
|
|
||||||
|
help: try using a const generic argument instead
|
||||||
|
|
|
||||||
|
LL | std::arch::x86_64::_mm_inserti_si64::<{ || () }, { 1 + (|| ()) }>(loop {}, loop {});
|
||||||
|
| ++++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user