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 10 pull requests #135891

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
de0cb6c
Start work on dangling pointers lint
Anthony-Eid Nov 13, 2024
6d95b5b
Update compiler/rustc_lint/src/lints.rs
Anthony-Eid Dec 5, 2024
bab8a41
Update compiler/rustc_lint/messages.ftl
Anthony-Eid Dec 5, 2024
3a83422
Fix ICE-133063
Shunpoco Jan 12, 2025
8a57fa6
Fix ICE-133117
Shunpoco Jan 12, 2025
8c0c149
Remove solved crashes
Shunpoco Jan 12, 2025
0385dd4
Fix ICE-130779
Shunpoco Jan 12, 2025
be56f10
Properly note when query stack is being cut off
compiler-errors Jan 16, 2025
cd9dcfc
ci: use ghcr buildkit image
marcoieni Jan 21, 2025
a93616a
rustc_resolve: remove unneeded `return`s
yotamofek Jan 18, 2025
cf91a93
rustc_resolve: flatten nested `if`s
yotamofek Jan 20, 2025
ae87d00
rustc_resolve: reduce rightwards drift with `let..else` 👉💨
yotamofek Jan 20, 2025
6f22dfe
rustc_resolve: use `Iterator` combinators instead of `for` loops wher…
yotamofek Jan 20, 2025
efabee2
rustc_resolve: don't open-code `Option::filter`
yotamofek Jan 21, 2025
fed5f98
Remove test panic from File::open
ChrisDenton Jan 21, 2025
922e6bb
Detect missing fields with default values and suggest `..`
estebank Jan 20, 2025
e727641
Reword "crate not found" resolve message
estebank Nov 18, 2024
57dd42d
Point at invalid utf-8 span on user's source code
estebank Jan 15, 2025
e7db092
address review: modify ICE-133117-duplicated-never-arm.rs
Shunpoco Jan 22, 2025
d8a216b
address review: modify ICE-133063-never-arm-no-otherwise-block.rs
Shunpoco Jan 22, 2025
481ed2d
address review: modify matches/mod.rs
Shunpoco Jan 22, 2025
7275bdf
modify comment
Shunpoco Jan 22, 2025
9e98d25
Library: Finalize dyn compatibility renaming
fmease Jan 22, 2025
12214db
Update lint tests with new dangling pointers message
Anthony-Eid Jan 22, 2025
5a36359
Rollup merge of #132983 - Anthony-Eid:dangling-pointers-lint, r=Urgau
matthiaskrgr Jan 22, 2025
f699947
Rollup merge of #133154 - estebank:issue-133137, r=wesleywiser
matthiaskrgr Jan 22, 2025
c2ea5ba
Rollup merge of #135409 - Shunpoco:issue-133117-ICE-never-false-edge-…
matthiaskrgr Jan 22, 2025
3cf5a81
Rollup merge of #135557 - estebank:wtf8, r=fee1-dead
matthiaskrgr Jan 22, 2025
b1285e1
Rollup merge of #135596 - compiler-errors:stack, r=oli-obk
matthiaskrgr Jan 22, 2025
8723964
Rollup merge of #135794 - estebank:non-exhaustive-dfv-ctor, r=jieyouxu
matthiaskrgr Jan 22, 2025
a634c4c
Rollup merge of #135814 - marcoieni:use-buildkit-ghcr, r=Kobzol
matthiaskrgr Jan 22, 2025
e98d9f5
Rollup merge of #135826 - yotamofek:resolve-cleanups4, r=petrochenkov
matthiaskrgr Jan 22, 2025
caf38c7
Rollup merge of #135837 - ChrisDenton:trunc, r=Noratrieb
matthiaskrgr Jan 22, 2025
578f0d7
Rollup merge of #135856 - fmease:library-mv-obj-save-dyn-compat-ii, r…
matthiaskrgr Jan 22, 2025
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 compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
#![feature(rustdoc_internals)]
#![feature(string_from_utf8_lossy_owned)]
#![feature(try_blocks)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_builtin_macros/src/source_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_expand::base::{
use rustc_expand::module::DirOwnership;
use rustc_lint_defs::BuiltinLintDiag;
use rustc_parse::parser::{ForceCollect, Parser};
use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal};
use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error};
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
use rustc_span::source_map::SourceMap;
use rustc_span::{Pos, Span, Symbol};
Expand Down Expand Up @@ -209,9 +209,10 @@ pub(crate) fn expand_include_str(
let interned_src = Symbol::intern(src);
MacEager::expr(cx.expr_str(cx.with_def_site_ctxt(bsp), interned_src))
}
Err(_) => {
let guar = cx.dcx().span_err(sp, format!("`{path}` wasn't a utf-8 file"));
DummyResult::any(sp, guar)
Err(utf8err) => {
let mut err = cx.dcx().struct_span_err(sp, format!("`{path}` wasn't a utf-8 file"));
utf8_error(cx.source_map(), path.as_str(), None, &mut err, utf8err, &bytes[..]);
DummyResult::any(sp, err.emit())
}
},
Err(dummy) => dummy,
Expand Down Expand Up @@ -273,7 +274,7 @@ fn load_binary_file(
.and_then(|path| path.into_os_string().into_string().ok());

if let Some(new_path) = new_path {
err.span_suggestion(
err.span_suggestion_verbose(
path_span,
"there is a file with the same name in a different directory",
format!("\"{}\"", new_path.replace('\\', "/").escape_debug()),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1528,9 +1528,9 @@ fn report_ice(
// If backtraces are enabled, also print the query stack
let backtrace = env::var_os("RUST_BACKTRACE").is_some_and(|x| &x != "0");

let num_frames = if backtrace { None } else { Some(2) };
let limit_frames = if backtrace { None } else { Some(2) };

interface::try_print_query_stack(dcx, num_frames, file);
interface::try_print_query_stack(dcx, limit_frames, file);

// We don't trust this callback not to panic itself, so run it at the end after we're sure we've
// printed all the relevant info.
Expand Down
30 changes: 30 additions & 0 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2349,6 +2349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.report_missing_fields(
adt_ty,
path_span,
expr.span,
remaining_fields,
variant,
hir_fields,
Expand Down Expand Up @@ -2386,6 +2387,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
adt_ty: Ty<'tcx>,
span: Span,
full_span: Span,
remaining_fields: UnordMap<Ident, (FieldIdx, &ty::FieldDef)>,
variant: &'tcx ty::VariantDef,
hir_fields: &'tcx [hir::ExprField<'tcx>],
Expand Down Expand Up @@ -2425,6 +2427,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}"));

if remaining_fields.items().all(|(_, (_, field))| field.value.is_some())
&& self.tcx.sess.is_nightly_build()
{
let msg = format!(
"all remaining fields have default values, {you_can} use those values with `..`",
you_can = if self.tcx.features().default_field_values() {
"you can"
} else {
"if you added `#![feature(default_field_values)]` to your crate you could"
},
);
if let Some(hir_field) = hir_fields.last() {
err.span_suggestion_verbose(
hir_field.span.shrink_to_hi(),
msg,
", ..".to_string(),
Applicability::MachineApplicable,
);
} else if hir_fields.is_empty() {
err.span_suggestion_verbose(
span.shrink_to_hi().with_hi(full_span.hi()),
msg,
" { .. }".to_string(),
Applicability::MachineApplicable,
);
}
}

if let Some(hir_field) = hir_fields.last() {
self.suggest_fru_from_range_and_emit(hir_field, variant, args, err);
} else {
Expand Down
17 changes: 11 additions & 6 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,31 +533,36 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se

pub fn try_print_query_stack(
dcx: DiagCtxtHandle<'_>,
num_frames: Option<usize>,
limit_frames: Option<usize>,
file: Option<std::fs::File>,
) {
eprintln!("query stack during panic:");

// Be careful relying on global state here: this code is called from
// a panic hook, which means that the global `DiagCtxt` may be in a weird
// state if it was responsible for triggering the panic.
let i = ty::tls::with_context_opt(|icx| {
let all_frames = ty::tls::with_context_opt(|icx| {
if let Some(icx) = icx {
ty::print::with_no_queries!(print_query_stack(
QueryCtxt::new(icx.tcx),
icx.query,
dcx,
num_frames,
limit_frames,
file,
))
} else {
0
}
});

if num_frames == None || num_frames >= Some(i) {
eprintln!("end of query stack");
if let Some(limit_frames) = limit_frames
&& all_frames > limit_frames
{
eprintln!(
"... and {} other queries... use `env RUST_BACKTRACE=1` to see the full query stack",
all_frames - limit_frames
);
} else {
eprintln!("we're just showing a limited slice of the query stack");
eprintln!("end of query stack");
}
}
4 changes: 3 additions & 1 deletion compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ lint_dangling_pointers_from_temporaries = a dangling pointer will be produced be
.label_ptr = this pointer will immediately be invalid
.label_temporary = this `{$ty}` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
.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
.help = for more information, see <https://doc.rust-lang.org/reference/destructors.html>
.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}`
.help_returned = in particular, if this pointer is returned from the current function, binding the `{$ty}` inside the function will not suffice
.help_visit = for more information, see <https://doc.rust-lang.org/reference/destructors.html>

lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance
.note = a `use rustc_data_structures::fx::{$preferred}` may be necessary
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,9 @@ pub(crate) struct IgnoredUnlessCrateSpecified<'a> {
#[derive(LintDiagnostic)]
#[diag(lint_dangling_pointers_from_temporaries)]
#[note]
#[help]
#[help(lint_help_bind)]
#[help(lint_help_returned)]
#[help(lint_help_visit)]
// FIXME: put #[primary_span] on `ptr_span` once it does not cause conflicts
pub(crate) struct DanglingPointersFromTemporaries<'tcx> {
pub callee: Symbol,
Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_mir_build/src/builder/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1986,6 +1986,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
return;
}

let false_edge_start_block = candidate.subcandidates[0].false_edge_start_block;
candidate.subcandidates.retain_mut(|candidate| {
if candidate.extra_data.is_never {
candidate.visit_leaves(|subcandidate| {
Expand All @@ -2000,8 +2001,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
});
if candidate.subcandidates.is_empty() {
// If `candidate` has become a leaf candidate, ensure it has a `pre_binding_block`.
candidate.pre_binding_block = Some(self.cfg.start_new_block());
// If `candidate` has become a leaf candidate, ensure it has a `pre_binding_block` and `otherwise_block`.
let next_block = self.cfg.start_new_block();
candidate.pre_binding_block = Some(next_block);
candidate.otherwise_block = Some(next_block);
// In addition, if `candidate` doesn't have `false_edge_start_block`, it should be assigned here.
if candidate.false_edge_start_block.is_none() {
candidate.false_edge_start_block = false_edge_start_block;
}
}
}

Expand Down
67 changes: 63 additions & 4 deletions compiler/rustc_parse/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,21 @@
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(string_from_utf8_lossy_owned)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end

use std::path::Path;
use std::path::{Path, PathBuf};
use std::str::Utf8Error;

use rustc_ast as ast;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{AttrItem, Attribute, MetaItemInner, token};
use rustc_ast_pretty::pprust;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Diag, FatalError, PResult};
use rustc_errors::{Diag, EmissionGuarantee, FatalError, PResult, pluralize};
use rustc_session::parse::ParseSess;
use rustc_span::source_map::SourceMap;
use rustc_span::{FileName, SourceFile, Span};
pub use unicode_normalization::UNICODE_VERSION as UNICODE_NORMALIZATION_VERSION;

Expand Down Expand Up @@ -73,9 +76,22 @@ pub fn new_parser_from_file<'a>(
path: &Path,
sp: Option<Span>,
) -> Result<Parser<'a>, Vec<Diag<'a>>> {
let source_file = psess.source_map().load_file(path).unwrap_or_else(|e| {
let msg = format!("couldn't read {}: {}", path.display(), e);
let sm = psess.source_map();
let source_file = sm.load_file(path).unwrap_or_else(|e| {
let msg = format!("couldn't read `{}`: {}", path.display(), e);
let mut err = psess.dcx().struct_fatal(msg);
if let Ok(contents) = std::fs::read(path)
&& let Err(utf8err) = String::from_utf8(contents.clone())
{
utf8_error(
sm,
&path.display().to_string(),
sp,
&mut err,
utf8err.utf8_error(),
&contents,
);
}
if let Some(sp) = sp {
err.span(sp);
}
Expand All @@ -84,6 +100,49 @@ pub fn new_parser_from_file<'a>(
new_parser_from_source_file(psess, source_file)
}

pub fn utf8_error<E: EmissionGuarantee>(
sm: &SourceMap,
path: &str,
sp: Option<Span>,
err: &mut Diag<'_, E>,
utf8err: Utf8Error,
contents: &[u8],
) {
// The file exists, but it wasn't valid UTF-8.
let start = utf8err.valid_up_to();
let note = format!("invalid utf-8 at byte `{start}`");
let msg = if let Some(len) = utf8err.error_len() {
format!(
"byte{s} `{bytes}` {are} not valid utf-8",
bytes = if len == 1 {
format!("{:?}", contents[start])
} else {
format!("{:?}", &contents[start..start + len])
},
s = pluralize!(len),
are = if len == 1 { "is" } else { "are" },
)
} else {
note.clone()
};
let contents = String::from_utf8_lossy(contents).to_string();
let source = sm.new_source_file(PathBuf::from(path).into(), contents);
let span = Span::with_root_ctxt(
source.normalized_byte_pos(start as u32),
source.normalized_byte_pos(start as u32),
);
if span.is_dummy() {
err.note(note);
} else {
if sp.is_some() {
err.span_note(span, msg);
} else {
err.span(span);
err.span_label(span, msg);
}
}
}

/// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing
/// the initial token stream.
fn new_parser_from_source_file(
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_query_system/src/query/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ pub fn print_query_stack<Qcx: QueryContext>(
qcx: Qcx,
mut current_query: Option<QueryJobId>,
dcx: DiagCtxtHandle<'_>,
num_frames: Option<usize>,
limit_frames: Option<usize>,
mut file: Option<std::fs::File>,
) -> usize {
// Be careful relying on global state here: this code is called from
Expand All @@ -584,7 +584,7 @@ pub fn print_query_stack<Qcx: QueryContext>(
let Some(query_info) = query_map.get(&query) else {
break;
};
if Some(count_printed) < num_frames || num_frames.is_none() {
if Some(count_printed) < limit_frames || limit_frames.is_none() {
// Only print to stderr as many stack frames as `num_frames` when present.
// FIXME: needs translation
#[allow(rustc::diagnostic_outside_of_impl)]
Expand Down Expand Up @@ -615,5 +615,5 @@ pub fn print_query_stack<Qcx: QueryContext>(
if let Some(ref mut file) = file {
let _ = writeln!(file, "end of query stack");
}
count_printed
count_total
}
54 changes: 26 additions & 28 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,10 +645,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let self_spans = items
.iter()
.filter_map(|(use_tree, _)| {
if let ast::UseTreeKind::Simple(..) = use_tree.kind {
if use_tree.ident().name == kw::SelfLower {
return Some(use_tree.span);
}
if let ast::UseTreeKind::Simple(..) = use_tree.kind
&& use_tree.ident().name == kw::SelfLower
{
return Some(use_tree.span);
}

None
Expand Down Expand Up @@ -947,19 +947,19 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let imported_binding = self.r.import(binding, import);
if parent == self.r.graph_root {
let ident = ident.normalize_to_macros_2_0();
if let Some(entry) = self.r.extern_prelude.get(&ident) {
if expansion != LocalExpnId::ROOT && orig_name.is_some() && !entry.is_import() {
self.r.dcx().emit_err(
errors::MacroExpandedExternCrateCannotShadowExternArguments {
span: item.span,
},
);
// `return` is intended to discard this binding because it's an
// unregistered ambiguity error which would result in a panic
// caused by inconsistency `path_res`
// more details: https://github.com/rust-lang/rust/pull/111761
return;
}
if let Some(entry) = self.r.extern_prelude.get(&ident)
&& expansion != LocalExpnId::ROOT
&& orig_name.is_some()
&& !entry.is_import()
{
self.r.dcx().emit_err(
errors::MacroExpandedExternCrateCannotShadowExternArguments { span: item.span },
);
// `return` is intended to discard this binding because it's an
// unregistered ambiguity error which would result in a panic
// caused by inconsistency `path_res`
// more details: https://github.com/rust-lang/rust/pull/111761
return;
}
let entry = self
.r
Expand Down Expand Up @@ -1040,10 +1040,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
span: item.span,
});
}
if let ItemKind::ExternCrate(Some(orig_name)) = item.kind {
if orig_name == kw::SelfLower {
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
}
if let ItemKind::ExternCrate(Some(orig_name)) = item.kind
&& orig_name == kw::SelfLower
{
self.r.dcx().emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
}
let ill_formed = |span| {
self.r.dcx().emit_err(errors::BadMacroImport { span });
Expand Down Expand Up @@ -1179,14 +1179,12 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
return Some((MacroKind::Bang, item.ident, item.span));
} else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
return Some((MacroKind::Attr, item.ident, item.span));
} else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
if let Some(meta_item_inner) =
} else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive)
&& let Some(meta_item_inner) =
attr.meta_item_list().and_then(|list| list.get(0).cloned())
{
if let Some(ident) = meta_item_inner.ident() {
return Some((MacroKind::Derive, ident, ident.span));
}
}
&& let Some(ident) = meta_item_inner.ident()
{
return Some((MacroKind::Derive, ident, ident.span));
}
None
}
Expand Down
Loading
Loading