Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a30f915

Browse files
committed
Auto merge of #135896 - matthiaskrgr:rollup-g6rv7za, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #132983 (Edit dangling pointers ) - #135409 (Fix ICE-133117: multiple never-pattern arm doesn't have false_edge_start_block) - #135557 (Point at invalid utf-8 span on user's source code) - #135596 (Properly note when query stack is being cut off) - #135794 (Detect missing fields with default values and suggest `..`) - #135814 (ci: use ghcr buildkit image) - #135826 (Misc. `rustc_resolve` cleanups) - #135837 (Remove test panic from File::open) - #135856 (Library: Finalize dyn compatibility renaming) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 649b995 + 3962bfa commit a30f915

File tree

55 files changed

+1079
-682
lines changed

Some content is hidden

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

55 files changed

+1079
-682
lines changed

‎compiler/rustc_builtin_macros/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#![feature(proc_macro_internals)]
1717
#![feature(proc_macro_quote)]
1818
#![feature(rustdoc_internals)]
19+
#![feature(string_from_utf8_lossy_owned)]
1920
#![feature(try_blocks)]
2021
#![warn(unreachable_pub)]
2122
// tidy-alphabetical-end

‎compiler/rustc_builtin_macros/src/source_util.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_expand::base::{
1313
use rustc_expand::module::DirOwnership;
1414
use rustc_lint_defs::BuiltinLintDiag;
1515
use rustc_parse::parser::{ForceCollect, Parser};
16-
use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
16+
use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error};
1717
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
1818
use rustc_span::source_map::SourceMap;
1919
use rustc_span::{Pos, Span, Symbol};
@@ -209,9 +209,10 @@ pub(crate) fn expand_include_str(
209209
let interned_src = Symbol::intern(src);
210210
MacEager::expr(cx.expr_str(cx.with_def_site_ctxt(bsp), interned_src))
211211
}
212-
Err(_) => {
213-
let guar = cx.dcx().span_err(sp, format!("`{path}` wasn't a utf-8 file"));
214-
DummyResult::any(sp, guar)
212+
Err(utf8err) => {
213+
let mut err = cx.dcx().struct_span_err(sp, format!("`{path}` wasn't a utf-8 file"));
214+
utf8_error(cx.source_map(), path.as_str(), None, &mut err, utf8err, &bytes[..]);
215+
DummyResult::any(sp, err.emit())
215216
}
216217
},
217218
Err(dummy) => dummy,
@@ -273,7 +274,7 @@ fn load_binary_file(
273274
.and_then(|path| path.into_os_string().into_string().ok());
274275

275276
if let Some(new_path) = new_path {
276-
err.span_suggestion(
277+
err.span_suggestion_verbose(
277278
path_span,
278279
"there is a file with the same name in a different directory",
279280
format!("\"{}\"", new_path.replace('\\', "/").escape_debug()),

‎compiler/rustc_driver_impl/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,9 +1528,9 @@ fn report_ice(
15281528
// If backtraces are enabled, also print the query stack
15291529
let backtrace = env::var_os("RUST_BACKTRACE").is_some_and(|x| &x != "0");
15301530

1531-
let num_frames = if backtrace { None } else { Some(2) };
1531+
let limit_frames = if backtrace { None } else { Some(2) };
15321532

1533-
interface::try_print_query_stack(dcx, num_frames, file);
1533+
interface::try_print_query_stack(dcx, limit_frames, file);
15341534

15351535
// We don't trust this callback not to panic itself, so run it at the end after we're sure we've
15361536
// printed all the relevant info.

‎compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2349,6 +2349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23492349
self.report_missing_fields(
23502350
adt_ty,
23512351
path_span,
2352+
expr.span,
23522353
remaining_fields,
23532354
variant,
23542355
hir_fields,
@@ -2386,6 +2387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23862387
&self,
23872388
adt_ty: Ty<'tcx>,
23882389
span: Span,
2390+
full_span: Span,
23892391
remaining_fields: UnordMap<Ident, (FieldIdx, &ty::FieldDef)>,
23902392
variant: &'tcx ty::VariantDef,
23912393
hir_fields: &'tcx [hir::ExprField<'tcx>],
@@ -2425,6 +2427,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24252427
);
24262428
err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}"));
24272429

2430+
if remaining_fields.items().all(|(_, (_, field))| field.value.is_some())
2431+
&& self.tcx.sess.is_nightly_build()
2432+
{
2433+
let msg = format!(
2434+
"all remaining fields have default values, {you_can} use those values with `..`",
2435+
you_can = if self.tcx.features().default_field_values() {
2436+
"you can"
2437+
} else {
2438+
"if you added `#![feature(default_field_values)]` to your crate you could"
2439+
},
2440+
);
2441+
if let Some(hir_field) = hir_fields.last() {
2442+
err.span_suggestion_verbose(
2443+
hir_field.span.shrink_to_hi(),
2444+
msg,
2445+
", ..".to_string(),
2446+
Applicability::MachineApplicable,
2447+
);
2448+
} else if hir_fields.is_empty() {
2449+
err.span_suggestion_verbose(
2450+
span.shrink_to_hi().with_hi(full_span.hi()),
2451+
msg,
2452+
" { .. }".to_string(),
2453+
Applicability::MachineApplicable,
2454+
);
2455+
}
2456+
}
2457+
24282458
if let Some(hir_field) = hir_fields.last() {
24292459
self.suggest_fru_from_range_and_emit(hir_field, variant, args, err);
24302460
} else {

‎compiler/rustc_interface/src/interface.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -533,31 +533,36 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
533533

534534
pub fn try_print_query_stack(
535535
dcx: DiagCtxtHandle<'_>,
536-
num_frames: Option<usize>,
536+
limit_frames: Option<usize>,
537537
file: Option<std::fs::File>,
538538
) {
539539
eprintln!("query stack during panic:");
540540

541541
// Be careful relying on global state here: this code is called from
542542
// a panic hook, which means that the global `DiagCtxt` may be in a weird
543543
// state if it was responsible for triggering the panic.
544-
let i = ty::tls::with_context_opt(|icx| {
544+
let all_frames = ty::tls::with_context_opt(|icx| {
545545
if let Some(icx) = icx {
546546
ty::print::with_no_queries!(print_query_stack(
547547
QueryCtxt::new(icx.tcx),
548548
icx.query,
549549
dcx,
550-
num_frames,
550+
limit_frames,
551551
file,
552552
))
553553
} else {
554554
0
555555
}
556556
});
557557

558-
if num_frames == None || num_frames >= Some(i) {
559-
eprintln!("end of query stack");
558+
if let Some(limit_frames) = limit_frames
559+
&& all_frames > limit_frames
560+
{
561+
eprintln!(
562+
"... and {} other queries... use `env RUST_BACKTRACE=1` to see the full query stack",
563+
all_frames - limit_frames
564+
);
560565
} else {
561-
eprintln!("we're just showing a limited slice of the query stack");
566+
eprintln!("end of query stack");
562567
}
563568
}

‎compiler/rustc_lint/messages.ftl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,9 @@ lint_dangling_pointers_from_temporaries = a dangling pointer will be produced be
209209
.label_ptr = this pointer will immediately be invalid
210210
.label_temporary = this `{$ty}` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
211211
.note = pointers do not have a lifetime; when calling `{$callee}` the `{$ty}` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
212-
.help = for more information, see <https://doc.rust-lang.org/reference/destructors.html>
212+
.help_bind = you must make sure that the variable you bind the `{$ty}` to lives at least as long as the pointer returned by the call to `{$callee}`
213+
.help_returned = in particular, if this pointer is returned from the current function, binding the `{$ty}` inside the function will not suffice
214+
.help_visit = for more information, see <https://doc.rust-lang.org/reference/destructors.html>
213215
214216
lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance
215217
.note = a `use rustc_data_structures::fx::{$preferred}` may be necessary

‎compiler/rustc_lint/src/lints.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,9 @@ pub(crate) struct IgnoredUnlessCrateSpecified<'a> {
11391139
#[derive(LintDiagnostic)]
11401140
#[diag(lint_dangling_pointers_from_temporaries)]
11411141
#[note]
1142-
#[help]
1142+
#[help(lint_help_bind)]
1143+
#[help(lint_help_returned)]
1144+
#[help(lint_help_visit)]
11431145
// FIXME: put #[primary_span] on `ptr_span` once it does not cause conflicts
11441146
pub(crate) struct DanglingPointersFromTemporaries<'tcx> {
11451147
pub callee: Symbol,

‎compiler/rustc_mir_build/src/builder/matches/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19861986
return;
19871987
}
19881988

1989+
let false_edge_start_block = candidate.subcandidates[0].false_edge_start_block;
19891990
candidate.subcandidates.retain_mut(|candidate| {
19901991
if candidate.extra_data.is_never {
19911992
candidate.visit_leaves(|subcandidate| {
@@ -2000,8 +2001,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20002001
}
20012002
});
20022003
if candidate.subcandidates.is_empty() {
2003-
// If `candidate` has become a leaf candidate, ensure it has a `pre_binding_block`.
2004-
candidate.pre_binding_block = Some(self.cfg.start_new_block());
2004+
// If `candidate` has become a leaf candidate, ensure it has a `pre_binding_block` and `otherwise_block`.
2005+
let next_block = self.cfg.start_new_block();
2006+
candidate.pre_binding_block = Some(next_block);
2007+
candidate.otherwise_block = Some(next_block);
2008+
// In addition, if `candidate` doesn't have `false_edge_start_block`, it should be assigned here.
2009+
if candidate.false_edge_start_block.is_none() {
2010+
candidate.false_edge_start_block = false_edge_start_block;
2011+
}
20052012
}
20062013
}
20072014

‎compiler/rustc_parse/src/lib.rs

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,21 @@
1111
#![feature(if_let_guard)]
1212
#![feature(iter_intersperse)]
1313
#![feature(let_chains)]
14+
#![feature(string_from_utf8_lossy_owned)]
1415
#![warn(unreachable_pub)]
1516
// tidy-alphabetical-end
1617

17-
use std::path::Path;
18+
use std::path::{Path, PathBuf};
19+
use std::str::Utf8Error;
1820

1921
use rustc_ast as ast;
2022
use rustc_ast::tokenstream::TokenStream;
2123
use rustc_ast::{AttrItem, Attribute, MetaItemInner, token};
2224
use rustc_ast_pretty::pprust;
2325
use rustc_data_structures::sync::Lrc;
24-
use rustc_errors::{Diag, FatalError, PResult};
26+
use rustc_errors::{Diag, EmissionGuarantee,FatalError, PResult, pluralize};
2527
use rustc_session::parse::ParseSess;
28+
use rustc_span::source_map::SourceMap;
2629
use rustc_span::{FileName, SourceFile, Span};
2730
pub use unicode_normalization::UNICODE_VERSION as UNICODE_NORMALIZATION_VERSION;
2831

@@ -73,9 +76,22 @@ pub fn new_parser_from_file<'a>(
7376
path: &Path,
7477
sp: Option<Span>,
7578
) -> Result<Parser<'a>, Vec<Diag<'a>>> {
76-
let source_file = psess.source_map().load_file(path).unwrap_or_else(|e| {
77-
let msg = format!("couldn't read {}: {}", path.display(), e);
79+
let sm = psess.source_map();
80+
let source_file = sm.load_file(path).unwrap_or_else(|e| {
81+
let msg = format!("couldn't read `{}`: {}", path.display(), e);
7882
let mut err = psess.dcx().struct_fatal(msg);
83+
if let Ok(contents) = std::fs::read(path)
84+
&& let Err(utf8err) = String::from_utf8(contents.clone())
85+
{
86+
utf8_error(
87+
sm,
88+
&path.display().to_string(),
89+
sp,
90+
&mut err,
91+
utf8err.utf8_error(),
92+
&contents,
93+
);
94+
}
7995
if let Some(sp) = sp {
8096
err.span(sp);
8197
}
@@ -84,6 +100,49 @@ pub fn new_parser_from_file<'a>(
84100
new_parser_from_source_file(psess, source_file)
85101
}
86102

103+
pub fn utf8_error<E: EmissionGuarantee>(
104+
sm: &SourceMap,
105+
path: &str,
106+
sp: Option<Span>,
107+
err: &mut Diag<'_, E>,
108+
utf8err: Utf8Error,
109+
contents: &[u8],
110+
) {
111+
// The file exists, but it wasn't valid UTF-8.
112+
let start = utf8err.valid_up_to();
113+
let note = format!("invalid utf-8 at byte `{start}`");
114+
let msg = if let Some(len) = utf8err.error_len() {
115+
format!(
116+
"byte{s} `{bytes}` {are} not valid utf-8",
117+
bytes = if len == 1 {
118+
format!("{:?}", contents[start])
119+
} else {
120+
format!("{:?}", &contents[start..start + len])
121+
},
122+
s = pluralize!(len),
123+
are = if len == 1 { "is" } else { "are" },
124+
)
125+
} else {
126+
note.clone()
127+
};
128+
let contents = String::from_utf8_lossy(contents).to_string();
129+
let source = sm.new_source_file(PathBuf::from(path).into(), contents);
130+
let span = Span::with_root_ctxt(
131+
source.normalized_byte_pos(start as u32),
132+
source.normalized_byte_pos(start as u32),
133+
);
134+
if span.is_dummy() {
135+
err.note(note);
136+
} else {
137+
if sp.is_some() {
138+
err.span_note(span, msg);
139+
} else {
140+
err.span(span);
141+
err.span_label(span, msg);
142+
}
143+
}
144+
}
145+
87146
/// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing
88147
/// the initial token stream.
89148
fn new_parser_from_source_file(

‎compiler/rustc_query_system/src/query/job.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ pub fn print_query_stack<Qcx: QueryContext>(
567567
qcx: Qcx,
568568
mut current_query: Option<QueryJobId>,
569569
dcx: DiagCtxtHandle<'_>,
570-
num_frames: Option<usize>,
570+
limit_frames: Option<usize>,
571571
mut file: Option<std::fs::File>,
572572
) -> usize {
573573
// Be careful relying on global state here: this code is called from
@@ -584,7 +584,7 @@ pub fn print_query_stack<Qcx: QueryContext>(
584584
let Some(query_info) = query_map.get(&query) else {
585585
break;
586586
};
587-
if Some(count_printed) < num_frames || num_frames.is_none() {
587+
if Some(count_printed) < limit_frames || limit_frames.is_none() {
588588
// Only print to stderr as many stack frames as `num_frames` when present.
589589
// FIXME: needs translation
590590
#[allow(rustc::diagnostic_outside_of_impl)]
@@ -615,5 +615,5 @@ pub fn print_query_stack<Qcx: QueryContext>(
615615
if let Some(ref mut file) = file {
616616
let _ = writeln!(file, "end of query stack");
617617
}
618-
count_printed
618+
count_total
619619
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /