Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 2 pull requests #133091

Closed
wants to merge 4 commits into from
Closed
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3270,6 +3270,7 @@ name = "rustc_ast_lowering"
version = "0.0.0"
dependencies = [
"rustc_ast",
"rustc_ast_pretty",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ doctest = false
[dependencies]
# tidy-alphabetical-start
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_ast_lowering/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ 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_legacy_const_generic_arg_suggestion =
try using a const generic argument instead

ast_lowering_invalid_register =
invalid register `{$reg}`: {$error}

Expand Down
23 changes: 23 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,26 @@ 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,
#[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,
}
70 changes: 67 additions & 3 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
use std::assert_matches::assert_matches;
use std::ops::ControlFlow;

use rustc_ast::ptr::P as AstP;
use rustc_ast::*;
use rustc_ast_pretty::pprust::expr_to_string;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lrc;
use rustc_hir as hir;
use rustc_hir::HirId;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::span_bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::errors::report_lit_error;
use rustc_span::source_map::{Spanned, respan};
use rustc_span::symbol::{Ident, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
use thin_vec::{ThinVec, thin_vec};
use visit::{Visitor, walk_expr};

use super::errors::{
AsyncCoroutinesNotSupported, AwaitOnlyInAsyncFnAndBlocks, BaseExpressionDoubleDot,
Expand All @@ -23,9 +27,32 @@ use super::errors::{
use super::{
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
};
use crate::errors::YieldInClosure;
use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure};
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> {
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 @@ -396,10 +423,34 @@ impl<'hir> LoweringContext<'_, 'hir> {
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
let mut real_args = vec![];
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) {
let parent_def_id = self.current_def_id_parent;
let node_id = self.next_node_id();
Expand All @@ -410,7 +461,20 @@ 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(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)));
} else {
real_args.push(arg);
Expand Down
20 changes: 15 additions & 5 deletions src/librustdoc/html/static/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,6 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
const quadcolon = /::\s*::/.exec(path);
if (path.startsWith("::")) {
throw ["Paths cannot start with ", "::"];
} else if (path.endsWith("::")) {
throw ["Paths cannot end with ", "::"];
} else if (quadcolon !== null) {
throw ["Unexpected ", quadcolon[0]];
}
Expand Down Expand Up @@ -3974,18 +3972,19 @@ class DocSearch {

if (parsedQuery.foundElems === 1 && !parsedQuery.hasReturnArrow) {
const elem = parsedQuery.elems[0];
for (const id of this.nameTrie.search(elem.normalizedPathLast, this.tailTable)) {
// use arrow functions to preserve `this`.
const handleNameSearch = (id) => {
const row = this.searchIndex[id];
if (!typePassesFilter(elem.typeFilter, row.ty) ||
(filterCrates !== null && row.crate !== filterCrates)) {
continue;
return;
}

let pathDist = 0;
if (elem.fullPath.length > 1) {
pathDist = checkPath(elem.pathWithoutLast, row);
if (pathDist === null) {
continue;
return;
}
}

Expand All @@ -4008,9 +4007,20 @@ class DocSearch {
maxEditDistance,
);
}
};
if (elem.normalizedPathLast !== "") {
const last = elem.normalizedPathLast;
for (const id of this.nameTrie.search(last, this.tailTable)) {
handleNameSearch(id);
}
}
const length = this.searchIndex.length;

for (let i = 0, nSearchIndex = length; i < nSearchIndex; ++i) {
// queries that end in :: bypass the trie
if (elem.normalizedPathLast === "") {
handleNameSearch(i);
}
const row = this.searchIndex[i];
if (filterCrates !== null && row.crate !== filterCrates) {
continue;
Expand Down
12 changes: 0 additions & 12 deletions tests/crashes/123077-2.rs

This file was deleted.

7 changes: 0 additions & 7 deletions tests/crashes/129150.rs

This file was deleted.

8 changes: 0 additions & 8 deletions tests/rustdoc-js-std/parser-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,6 @@ const PARSED = [
returned: [],
error: "Unexpected `:: ::`",
},
{
query: "a::b::",
elems: [],
foundElems: 0,
userQuery: "a::b::",
returned: [],
error: "Paths cannot end with `::`",
},
{
query: ":a",
elems: [],
Expand Down
6 changes: 6 additions & 0 deletions tests/rustdoc-js-std/path-end-empty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const EXPECTED = {
'query': 'Option::',
'others': [
{ 'path': 'std::option::Option', 'name': 'get_or_insert_default' },
],
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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