Skip to content

Commit c33ba48

Browse files
committed
Auto merge of rust-lang#122229 - jhpratt:rollup-o2dscvq, r=jhpratt
Rollup of 12 pull requests Successful merges: - rust-lang#99153 (Add Read Impl for &Stdin) - rust-lang#112136 (Add std::ffi::c_str module) - rust-lang#120504 (Vec::try_with_capacity) - rust-lang#121280 (Implement MaybeUninit::fill{,_with,_from}) - rust-lang#121813 (Misc improvements to non local defs lint implementation) - rust-lang#121833 (Suggest correct path in include_bytes!) - rust-lang#121860 (Add a tidy check that checks whether the fluent slugs only appear once) - rust-lang#122160 (Eagerly translate `HelpUseLatestEdition` in parser diagnostics) - rust-lang#122178 (ci: add a runner for vanilla LLVM 18) - rust-lang#122186 (Remove a workaround for a bug) - rust-lang#122215 (Some tweaks to the parallel query cycle handler) - rust-lang#122223 (Fix typo in `VisitorResult`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9d272a1 + d5956a9 commit c33ba48

File tree

57 files changed

+1208
-224
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1208
-224
lines changed

.github/workflows/ci.yml

+4
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,10 @@ jobs:
315315
- name: x86_64-gnu-distcheck
316316
os: ubuntu-20.04-8core-32gb
317317
env: {}
318+
- name: x86_64-gnu-llvm-18
319+
env:
320+
RUST_BACKTRACE: 1
321+
os: ubuntu-20.04-8core-32gb
318322
- name: x86_64-gnu-llvm-17
319323
env:
320324
RUST_BACKTRACE: 1

Cargo.lock

-1
Original file line numberDiff line numberDiff line change
@@ -4133,7 +4133,6 @@ dependencies = [
41334133
"rustc_target",
41344134
"rustc_trait_selection",
41354135
"rustc_type_ir",
4136-
"smallvec",
41374136
"tracing",
41384137
"unicode-security",
41394138
]

compiler/rustc_ast_ir/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ impl VisitorResult for () {
1414
type Residual = !;
1515

1616
#[cfg(not(feature = "nightly"))]
17-
type Residual = core::ops::Infallible;
17+
type Residual = core::convert::Infallible;
1818

1919
fn output() -> Self {}
2020
fn from_residual(_: Self::Residual) -> Self {}

compiler/rustc_builtin_macros/src/source_util.rs

+120-30
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ use rustc_ast::ptr::P;
33
use rustc_ast::token;
44
use rustc_ast::tokenstream::TokenStream;
55
use rustc_ast_pretty::pprust;
6+
use rustc_data_structures::sync::Lrc;
67
use rustc_expand::base::{
7-
check_zero_tts, get_single_str_from_tts, parse_expr, resolve_path, DummyResult, ExtCtxt,
8-
MacEager, MacResult,
8+
check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr,
9+
resolve_path, DummyResult, ExtCtxt, MacEager, MacResult,
910
};
1011
use rustc_expand::module::DirOwnership;
1112
use rustc_parse::new_parser_from_file;
1213
use rustc_parse::parser::{ForceCollect, Parser};
1314
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
15+
use rustc_span::source_map::SourceMap;
1416
use rustc_span::symbol::Symbol;
1517
use rustc_span::{Pos, Span};
16-
1718
use smallvec::SmallVec;
19+
use std::path::{Path, PathBuf};
1820
use std::rc::Rc;
1921

2022
// These macros all relate to the file system; they either return
@@ -180,32 +182,22 @@ pub fn expand_include_str(
180182
tts: TokenStream,
181183
) -> Box<dyn MacResult + 'static> {
182184
let sp = cx.with_def_site_ctxt(sp);
183-
let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
184-
Ok(file) => file,
185+
let (path, path_span) = match get_single_str_spanned_from_tts(cx, sp, tts, "include_str!") {
186+
Ok(res) => res,
185187
Err(guar) => return DummyResult::any(sp, guar),
186188
};
187-
let file = match resolve_path(&cx.sess, file.as_str(), sp) {
188-
Ok(f) => f,
189-
Err(err) => {
190-
let guar = err.emit();
191-
return DummyResult::any(sp, guar);
192-
}
193-
};
194-
match cx.source_map().load_binary_file(&file) {
189+
match load_binary_file(cx, path.as_str().as_ref(), sp, path_span) {
195190
Ok(bytes) => match std::str::from_utf8(&bytes) {
196191
Ok(src) => {
197192
let interned_src = Symbol::intern(src);
198193
MacEager::expr(cx.expr_str(sp, interned_src))
199194
}
200195
Err(_) => {
201-
let guar = cx.dcx().span_err(sp, format!("{} wasn't a utf-8 file", file.display()));
196+
let guar = cx.dcx().span_err(sp, format!("`{path}` wasn't a utf-8 file"));
202197
DummyResult::any(sp, guar)
203198
}
204199
},
205-
Err(e) => {
206-
let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
207-
DummyResult::any(sp, guar)
208-
}
200+
Err(dummy) => dummy,
209201
}
210202
}
211203

@@ -215,25 +207,123 @@ pub fn expand_include_bytes(
215207
tts: TokenStream,
216208
) -> Box<dyn MacResult + 'static> {
217209
let sp = cx.with_def_site_ctxt(sp);
218-
let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
219-
Ok(file) => file,
210+
let (path, path_span) = match get_single_str_spanned_from_tts(cx, sp, tts, "include_bytes!") {
211+
Ok(res) => res,
220212
Err(guar) => return DummyResult::any(sp, guar),
221213
};
222-
let file = match resolve_path(&cx.sess, file.as_str(), sp) {
223-
Ok(f) => f,
214+
match load_binary_file(cx, path.as_str().as_ref(), sp, path_span) {
215+
Ok(bytes) => {
216+
let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes));
217+
MacEager::expr(expr)
218+
}
219+
Err(dummy) => dummy,
220+
}
221+
}
222+
223+
fn load_binary_file(
224+
cx: &mut ExtCtxt<'_>,
225+
original_path: &Path,
226+
macro_span: Span,
227+
path_span: Span,
228+
) -> Result<Lrc<[u8]>, Box<dyn MacResult>> {
229+
let resolved_path = match resolve_path(&cx.sess, original_path, macro_span) {
230+
Ok(path) => path,
224231
Err(err) => {
225232
let guar = err.emit();
226-
return DummyResult::any(sp, guar);
233+
return Err(DummyResult::any(macro_span, guar));
227234
}
228235
};
229-
match cx.source_map().load_binary_file(&file) {
230-
Ok(bytes) => {
231-
let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes));
232-
MacEager::expr(expr)
236+
match cx.source_map().load_binary_file(&resolved_path) {
237+
Ok(data) => Ok(data),
238+
Err(io_err) => {
239+
let mut err = cx.dcx().struct_span_err(
240+
macro_span,
241+
format!("couldn't read `{}`: {io_err}", resolved_path.display()),
242+
);
243+
244+
if original_path.is_relative() {
245+
let source_map = cx.sess.source_map();
246+
let new_path = source_map
247+
.span_to_filename(macro_span.source_callsite())
248+
.into_local_path()
249+
.and_then(|src| find_path_suggestion(source_map, src.parent()?, original_path))
250+
.and_then(|path| path.into_os_string().into_string().ok());
251+
252+
if let Some(new_path) = new_path {
253+
err.span_suggestion(
254+
path_span,
255+
"there is a file with the same name in a different directory",
256+
format!("\"{}\"", new_path.escape_debug()),
257+
rustc_lint_defs::Applicability::MachineApplicable,
258+
);
259+
}
260+
}
261+
let guar = err.emit();
262+
Err(DummyResult::any(macro_span, guar))
233263
}
234-
Err(e) => {
235-
let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
236-
DummyResult::any(sp, guar)
264+
}
265+
}
266+
267+
fn find_path_suggestion(
268+
source_map: &SourceMap,
269+
base_dir: &Path,
270+
wanted_path: &Path,
271+
) -> Option<PathBuf> {
272+
// Fix paths that assume they're relative to cargo manifest dir
273+
let mut base_c = base_dir.components();
274+
let mut wanted_c = wanted_path.components();
275+
let mut without_base = None;
276+
while let Some(wanted_next) = wanted_c.next() {
277+
if wanted_c.as_path().file_name().is_none() {
278+
break;
279+
}
280+
// base_dir may be absolute
281+
while let Some(base_next) = base_c.next() {
282+
if base_next == wanted_next {
283+
without_base = Some(wanted_c.as_path());
284+
break;
285+
}
286+
}
287+
}
288+
let root_absolute = without_base.into_iter().map(PathBuf::from);
289+
290+
let base_dir_components = base_dir.components().count();
291+
// Avoid going all the way to the root dir
292+
let max_parent_components = if base_dir.is_relative() {
293+
base_dir_components + 1
294+
} else {
295+
base_dir_components.saturating_sub(1)
296+
};
297+
298+
// Try with additional leading ../
299+
let mut prefix = PathBuf::new();
300+
let add = std::iter::from_fn(|| {
301+
prefix.push("..");
302+
Some(prefix.join(wanted_path))
303+
})
304+
.take(max_parent_components.min(3));
305+
306+
// Try without leading directories
307+
let mut trimmed_path = wanted_path;
308+
let remove = std::iter::from_fn(|| {
309+
let mut components = trimmed_path.components();
310+
let removed = components.next()?;
311+
trimmed_path = components.as_path();
312+
let _ = trimmed_path.file_name()?; // ensure there is a file name left
313+
Some([
314+
Some(trimmed_path.to_path_buf()),
315+
(removed != std::path::Component::ParentDir)
316+
.then(|| Path::new("..").join(trimmed_path)),
317+
])
318+
})
319+
.flatten()
320+
.flatten()
321+
.take(4);
322+
323+
for new_path in root_absolute.chain(add).chain(remove) {
324+
if source_map.file_exists(&base_dir.join(&new_path)) {
325+
return Some(new_path);
237326
}
238327
}
328+
None
239329
}

compiler/rustc_const_eval/messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,6 @@ const_eval_intern_kind = {$kind ->
146146
*[other] {""}
147147
}
148148
149-
const_eval_invalid_align =
150-
align has to be a power of 2
151-
152149
const_eval_invalid_align_details =
153150
invalid align passed to `{$name}`: {$align} is {$err_kind ->
154151
[not_power_of_two] not a power of 2

compiler/rustc_expand/src/base.rs

+26-15
Original file line numberDiff line numberDiff line change
@@ -1233,21 +1233,18 @@ pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PRe
12331233
// after macro expansion (that is, they are unhygienic).
12341234
if !path.is_absolute() {
12351235
let callsite = span.source_callsite();
1236-
let mut result = match sess.source_map().span_to_filename(callsite) {
1237-
FileName::Real(name) => name
1238-
.into_local_path()
1239-
.expect("attempting to resolve a file path in an external file"),
1240-
FileName::DocTest(path, _) => path,
1241-
other => {
1242-
return Err(sess.dcx().create_err(errors::ResolveRelativePath {
1243-
span,
1244-
path: sess.source_map().filename_for_diagnostics(&other).to_string(),
1245-
}));
1246-
}
1236+
let source_map = sess.source_map();
1237+
let Some(mut base_path) = source_map.span_to_filename(callsite).into_local_path() else {
1238+
return Err(sess.dcx().create_err(errors::ResolveRelativePath {
1239+
span,
1240+
path: source_map
1241+
.filename_for_diagnostics(&source_map.span_to_filename(callsite))
1242+
.to_string(),
1243+
}));
12471244
};
1248-
result.pop();
1249-
result.push(path);
1250-
Ok(result)
1245+
base_path.pop();
1246+
base_path.push(path);
1247+
Ok(base_path)
12511248
} else {
12521249
Ok(path)
12531250
}
@@ -1344,6 +1341,15 @@ pub fn get_single_str_from_tts(
13441341
tts: TokenStream,
13451342
name: &str,
13461343
) -> Result<Symbol, ErrorGuaranteed> {
1344+
get_single_str_spanned_from_tts(cx, span, tts, name).map(|(s, _)| s)
1345+
}
1346+
1347+
pub fn get_single_str_spanned_from_tts(
1348+
cx: &mut ExtCtxt<'_>,
1349+
span: Span,
1350+
tts: TokenStream,
1351+
name: &str,
1352+
) -> Result<(Symbol, Span), ErrorGuaranteed> {
13471353
let mut p = cx.new_parser_from_tts(tts);
13481354
if p.token == token::Eof {
13491355
let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
@@ -1355,7 +1361,12 @@ pub fn get_single_str_from_tts(
13551361
if p.token != token::Eof {
13561362
cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
13571363
}
1358-
expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s)
1364+
expr_to_spanned_string(cx, ret, "argument must be a string literal")
1365+
.map_err(|err| match err {
1366+
Ok((err, _)) => err.emit(),
1367+
Err(guar) => guar,
1368+
})
1369+
.map(|(symbol, _style, span)| (symbol, span))
13591370
}
13601371

13611372
/// Extracts comma-separated expressions from `tts`.

compiler/rustc_infer/messages.ftl

-8
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,6 @@ infer_more_targeted = {$has_param_name ->
181181
182182
infer_msl_introduces_static = introduces a `'static` lifetime requirement
183183
infer_msl_unmet_req = because this has an unmet lifetime requirement
184-
infer_need_type_info_in_coroutine =
185-
type inside {$coroutine_kind ->
186-
[async_block] `async` block
187-
[async_closure] `async` closure
188-
[async_fn] `async fn` body
189-
*[coroutine] coroutine
190-
} must be known in this context
191-
192184
193185
infer_nothing = {""}
194186

compiler/rustc_interface/src/util.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,11 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
101101
threads: usize,
102102
f: F,
103103
) -> R {
104-
use rustc_data_structures::{jobserver, sync::FromDyn};
104+
use rustc_data_structures::{defer, jobserver, sync::FromDyn};
105105
use rustc_middle::ty::tls;
106106
use rustc_query_impl::QueryCtxt;
107-
use rustc_query_system::query::{deadlock, QueryContext};
107+
use rustc_query_system::query::{break_query_cycles, QueryContext};
108+
use std::process;
108109

109110
let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap());
110111

@@ -128,7 +129,19 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
128129
let query_map =
129130
FromDyn::from(tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs()));
130131
let registry = rayon_core::Registry::current();
131-
thread::spawn(move || deadlock(query_map.into_inner(), &registry));
132+
thread::Builder::new()
133+
.name("rustc query cycle handler".to_string())
134+
.spawn(move || {
135+
let on_panic = defer(|| {
136+
eprintln!("query cycle handler thread panicked, aborting process");
137+
// We need to abort here as we failed to resolve the deadlock,
138+
// otherwise the compiler could just hang,
139+
process::abort();
140+
});
141+
break_query_cycles(query_map.into_inner(), &registry);
142+
on_panic.disable();
143+
})
144+
.unwrap();
132145
});
133146
if let Some(size) = get_stack_size() {
134147
builder = builder.stack_size(size);

compiler/rustc_lint/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ rustc_span = { path = "../rustc_span" }
2323
rustc_target = { path = "../rustc_target" }
2424
rustc_trait_selection = { path = "../rustc_trait_selection" }
2525
rustc_type_ir = { path = "../rustc_type_ir" }
26-
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
2726
tracing = "0.1"
2827
unicode-security = "0.1.0"
2928
# tidy-alphabetical-end

compiler/rustc_lint/messages.ftl

-2
Original file line numberDiff line numberDiff line change
@@ -562,8 +562,6 @@ lint_suspicious_double_ref_clone =
562562
lint_suspicious_double_ref_deref =
563563
using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type
564564
565-
lint_trivial_untranslatable_diag = diagnostic with static strings only
566-
567565
lint_ty_qualified = usage of qualified `ty::{$ty}`
568566
.suggestion = try importing it and using it unqualified
569567

0 commit comments

Comments
 (0)