Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
9363038
bootstrap: fix RUSTFLAGS with spaces in paths via CARGO_ENCODED_RUSTF…
Rohan-Singla Jun 18, 2026
63d3395
bootstrap: also use CARGO_ENCODED_RUSTDOCFLAGS to support spaces in…
Rohan-Singla Jun 18, 2026
386748b
⏺ bootstrap: reset CARGO_ENCODED_RUSTFLAGS in Miri test runner
Rohan-Singla Jun 18, 2026
8085cd3
bootstrap: use \x1f-delimited String for Rustflags instead of Vec<Str…
Rohan-Singla Jun 18, 2026
b4a7c3e
unset RUSTFLAGS/RUSTDOCFLAGS when setting encoded forms
Rohan-Singla Jun 21, 2026
a13e2da
rustc: improve diagnostics for file-open failures
Unique-Usman Jun 23, 2026
9aaea56
Recover deferred closure calls after errors
Dnreikronos Jun 27, 2026
a89705b
Avoid panics bubbling out to proc macros
Mark-Simulacrum Jun 22, 2026
bd938c5
Include default-stability info in rustdoc JSON.
obi1kenobi Jun 27, 2026
7f2574f
Move attribute and keyword docs from `std` to `core`
jschillem Jun 28, 2026
cca8cd1
Use doctest attribute `ignore-wasm` instead of manual `cfg_attr`
fmease Jun 29, 2026
5fd9908
Rollup merge of #158073 - Rohan-Singla:fix/#158052, r=kobzol,mark-sim…
jhpratt Jun 29, 2026
9695129
Rollup merge of #158256 - Mark-Simulacrum:no-panic-pm-parsing, r=bjorn3
jhpratt Jun 29, 2026
f0ece34
Rollup merge of #158081 - Dnreikronos:trait_system/deferred_closure_r…
jhpratt Jun 29, 2026
8148b29
Rollup merge of #158323 - Unique-Usman:ua/invalid_source_file, r=nnet…
jhpratt Jun 29, 2026
2a19695
Rollup merge of #158327 - jschillem:docs-move-attributes-and-keywords…
jhpratt Jun 29, 2026
f87af78
Rollup merge of #158468 - obi1kenobi:pg/default-body-stability, r=Gui…
jhpratt Jun 29, 2026
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
21 changes: 13 additions & 8 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,11 @@ impl server::Server for Rustc<'_, '_> {
fn literal_from_str(&mut self, s: &str) -> Result<Literal<Self::Span, Self::Symbol>, String> {
let name = FileName::proc_macro_source_code(s);

let mut parser =
let mut parser = rustc_errors::catch_fatal_errors(|| {
new_parser_from_source_str(self.psess(), name, s.to_owned(), StripTokens::Nothing)
.map_err(cancel_diags_into_string)?;
})
.map_err(|_| String::from("failed to parse to literal"))?
.map_err(cancel_diags_into_string)?;

let first_span = parser.token.span.data();
let minus_present = parser.eat(exp!(Minus));
Expand Down Expand Up @@ -569,12 +571,15 @@ impl server::Server for Rustc<'_, '_> {
}

fn ts_from_str(&mut self, src: &str) -> Result<Self::TokenStream, String> {
source_str_to_stream(
self.psess(),
FileName::proc_macro_source_code(src),
src.to_string(),
Some(self.call_site),
)
rustc_errors::catch_fatal_errors(|| {
source_str_to_stream(
self.psess(),
FileName::proc_macro_source_code(src),
src.to_string(),
Some(self.call_site),
)
})
.map_err(|_| String::from("failed to parse to tokenstream"))?
.map_err(cancel_diags_into_string)
}

Expand Down
17 changes: 11 additions & 6 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ use rustc_hir::{self as hir, HirId, LangItem, find_attr};
use rustc_hir_analysis::autoderef::Autoderef;
use rustc_infer::infer::BoundRegionConversionTime;
use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode};
use rustc_middle::bug;
use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
};
use rustc_middle::ty::{self, FnSig, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, Unnormalized};
use rustc_middle::{bug, span_bug};
use rustc_span::def_id::LocalDefId;
use rustc_span::{Ident, Span, sym};
use rustc_target::spec::{AbiMap, AbiMapping};
Expand Down Expand Up @@ -1186,11 +1186,16 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> {
);
}
None => {
span_bug!(
self.call_expr.span,
"Expected to find a suitable `Fn`/`FnMut`/`FnOnce` implementation for `{}`",
self.closure_ty
)
let guar = fcx.tainted_by_errors().unwrap_or_else(|| {
fcx.dcx().span_delayed_bug(
self.call_expr.span,
format!(
"Expected to find a suitable `Fn`/`FnMut`/`FnOnce` implementation for `{}`",
self.closure_ty
),
)
});
fcx.write_resolution(self.call_expr.hir_id, Err(guar));
}
}
}
Expand Down
41 changes: 39 additions & 2 deletions compiler/rustc_parse/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ use rustc_ast_pretty::pprust;
use rustc_errors::{Diag, EmissionGuarantee, FatalError, PResult, pluralize};
pub use rustc_lexer::UNICODE_VERSION;
use rustc_session::parse::ParseSess;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::source_map::SourceMap;
use rustc_span::{FileName, SourceFile, Span};
use rustc_span::{FileName, SourceFile, Span, Symbol};

pub const MACRO_ARGUMENTS: Option<&str> = Some("macro arguments");

Expand Down Expand Up @@ -105,6 +106,8 @@ pub fn new_parser_from_source_str(
/// dropped.
///
/// If a span is given, that is used on an error as the source of the problem.
///
/// Error messages are tailored to the specific error kind.
pub fn new_parser_from_file<'a>(
psess: &'a ParseSess,
path: &Path,
Expand All @@ -113,8 +116,42 @@ pub fn new_parser_from_file<'a>(
) -> Result<Parser<'a>, Vec<Diag<'a>>> {
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);
use std::io::ErrorKind;

let msg = match e.kind() {
ErrorKind::NotFound => format!("couldn't find file `{}`", path.display()),
ErrorKind::PermissionDenied => {
format!("permission denied when opening file `{}`", path.display())
}
ErrorKind::IsADirectory => format!("`{}` is a directory", path.display()),
_ => format!("couldn't read `{}`: {}", path.display(), e),
};

let mut err = psess.dcx().struct_fatal(msg);

if e.kind() == ErrorKind::NotFound {
if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) {
let parent = match path.parent() {
Some(p) if !p.as_os_str().is_empty() => p,
_ => Path::new("."),
};
if let Ok(entries) = std::fs::read_dir(parent) {
let candidates: Vec<Symbol> = entries
.flatten()
.filter_map(|entry| entry.file_name().to_str().map(Symbol::intern))
.collect();
let lookup = Symbol::intern(file_name);
if let Some(suggestion) = find_best_match_for_name(&candidates, lookup, None) {
let suggested_path = if parent == Path::new(".") {
suggestion.as_str().to_string()
} else {
parent.join(suggestion.as_str()).display().to_string()
};
err.help(format!("you might have meant to open `{}`", suggested_path));
}
}
}
}
if let Ok(contents) = std::fs::read(path)
&& let Err(utf8err) = std::str::from_utf8(&contents)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2556,6 +2556,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
err.children.clear();

let mut span = obligation.cause.span;
let mut is_async_fn_return = false;
if let DefKind::Closure = self.tcx.def_kind(obligation.cause.body_id)
&& let parent = self.tcx.local_parent(obligation.cause.body_id)
&& let DefKind::Fn | DefKind::AssocFn = self.tcx.def_kind(parent)
Expand All @@ -2571,10 +2572,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// and
// async fn foo() -> dyn Display Box<dyn { .. }>
span = fn_sig.decl.output.span();
is_async_fn_return = true;
err.span(span);
}
let body = self.tcx.hir_body_owned_by(obligation.cause.body_id);

if !is_async_fn_return
&& let Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(closure), .. }) =
self.tcx.hir_node_by_def_id(obligation.cause.body_id)
&& matches!(closure.fn_decl.output, hir::FnRetTy::DefaultReturn(_))
{
return true;
}

let mut visitor = ReturnsVisitor::default();
visitor.visit_body(&body);

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ mod break_keyword {}
/// to be most things that would be reasonable to have in a constant (barring `const fn`s). For
/// example, you can't have a [`File`] as a `const`.
///
/// [`File`]: crate::fs::File
/// [`File`]: ../std/fs/struct.File.html
///
/// The only lifetime allowed in a constant is `'static`, which is the lifetime that encompasses
/// all others in a Rust program. For example, if you wanted to define a constant string, it would
Expand Down Expand Up @@ -484,7 +484,7 @@ mod extern_keyword {}

#[doc(keyword = "false")]
//
/// A value of type [`bool`] representing logical **false**.
/// A value of type [`prim@bool`] representing logical **false**.
///
/// `false` is the logical opposite of [`true`].
///
Expand Down Expand Up @@ -1060,7 +1060,8 @@ mod mod_keyword {}
///
/// `move` is often used when [threads] are involved.
///
/// ```rust
#[cfg_attr(target_os = "wasi", doc = "```rust,ignore (thread::spawn not supported)")]
#[cfg_attr(not(target_os = "wasi"), doc = "```rust")]
/// let data = vec![1, 2, 3];
///
/// std::thread::spawn(move || {
Expand Down Expand Up @@ -1235,31 +1236,18 @@ mod ref_keyword {}
/// `return` returns from the function immediately (an "early return"):
///
/// ```no_run
/// use std::fs::File;
/// use std::io::{Error, ErrorKind, Read, Result};
///
/// fn main() -> Result<()> {
/// let mut file = match File::open("foo.txt") {
/// Ok(f) => f,
/// Err(e) => return Err(e),
/// };
/// fn main() -> Result<(), &'static str> {
/// let contents = "Hello, world!";
///
/// let mut contents = String::new();
/// let size = match file.read_to_string(&mut contents) {
/// Ok(s) => s,
/// Err(e) => return Err(e),
/// };
/// if contents.contains("impossible!") {
/// return Err("oh no!");
/// }
///
/// if contents.contains("impossible!") {
/// return Err(Error::new(ErrorKind::Other, "oh no!"));
/// }
/// if contents.len() > 9000 {
/// return Err("over 9000!");
/// }
///
/// if size > 9000 {
/// return Err(Error::new(ErrorKind::Other, "over 9000!"));
/// }
///
/// assert_eq!(contents, "Hello, world!");
/// Ok(())
/// Ok(())
/// }
/// ```
///
Expand Down Expand Up @@ -1306,7 +1294,8 @@ mod return_keyword {}
/// manner to computed goto).
///
/// Example of using `become` to implement functional-style `fold`:
/// ```
///
/// ```ignore-wasm (tail-call target feature not enabled by default on wasm)
/// #![feature(explicit_tail_calls)]
/// #![expect(incomplete_features)]
///
Expand Down Expand Up @@ -1360,7 +1349,8 @@ mod return_keyword {}
/// (unless it's coerced to a function pointer)
///
/// It is possible to tail-call a function pointer:
/// ```
///
/// ```ignore-wasm (tail-call target feature not enabled by default on wasm)
/// #![feature(explicit_tail_calls)]
/// #![expect(incomplete_features)]
///
Expand Down Expand Up @@ -1631,8 +1621,8 @@ mod self_upper_keyword {}
/// [`extern`]: keyword.extern.html
/// [`mut`]: keyword.mut.html
/// [`unsafe`]: keyword.unsafe.html
/// [`Mutex`]: sync::Mutex
/// [`OnceLock`]: sync::OnceLock
/// [`Mutex`]: ../std/sync/struct.Mutex.html
/// [`OnceLock`]: ../std/sync/struct.OnceLock.html
/// [`RefCell`]: cell::RefCell
/// [atomic]: sync::atomic
/// [Reference]: ../reference/items/static-items.html
Expand Down Expand Up @@ -1959,7 +1949,7 @@ mod trait_keyword {}

#[doc(keyword = "true")]
//
/// A value of type [`bool`] representing logical **true**.
/// A value of type [`prim@bool`] representing logical **true**.
///
/// Logically `true` is not equal to [`false`].
///
Expand Down Expand Up @@ -2312,6 +2302,7 @@ mod type_keyword {}
/// [`static`]: keyword.static.html
/// [`union`]: keyword.union.html
/// [`impl`]: keyword.impl.html
/// [`Vec::set_len`]: ../std/vec/struct.Vec.html#method.set_len
/// [raw pointers]: ../reference/types/pointer.html
/// [memory safety]: ../book/ch19-01-unsafe-rust.html
/// [Rustonomicon]: ../nomicon/index.html
Expand Down Expand Up @@ -2502,7 +2493,7 @@ mod use_keyword {}
/// ```
///
/// `where` is available anywhere generic and lifetime parameters are available,
/// as can be seen with the [`Cow`](crate::borrow::Cow) type from the standard
/// as can be seen with the [`Cow`](../std/borrow/enum.Cow.html) type from the standard
/// library:
///
/// ```rust
Expand Down
13 changes: 13 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,4 +386,17 @@ pub mod simd {
pub use crate::core_simd::simd::*;
}

// Include private modules that exist solely to provide rustdoc
// documentation for built-in attributes. Using `include!` because rustdoc
// only looks for these modules at the crate level.
include!("attribute_docs.rs");

// Include a number of private modules that exist solely to provide
// the rustdoc documentation for the existing keywords. Using `include!`
// because rustdoc only looks for these modules at the crate level.
include!("keyword_docs.rs");

// Include a number of private modules that exist solely to provide
// the rustdoc documentation for primitive types. Using `include!`
// because rustdoc only looks for these modules at the crate level.
include!("primitive_docs.rs");
21 changes: 12 additions & 9 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,20 +772,23 @@ pub mod from {
pub use core::from::From;
}

// Include a number of private modules that exist solely to provide
// the rustdoc documentation for primitive types. Using `include!`
// because rustdoc only looks for these modules at the crate level.
include!("../../core/src/primitive_docs.rs");
// We include the following files here *again* (they are already included in libcore)
// so that they show up in search results for the std crate, and to avoid breaking
// existing links:

// documentation for built-in attributes. Using `include!` because rustdoc
// only looks for these modules at the crate level.
include!("../../core/src/attribute_docs.rs");

// Include a number of private modules that exist solely to provide
// the rustdoc documentation for the existing keywords. Using `include!`
// because rustdoc only looks for these modules at the crate level.
include!("keyword_docs.rs");
include!("../../core/src/keyword_docs.rs");

// Include private modules that exist solely to provide rustdoc
// documentation for built-in attributes. Using `include!` because rustdoc
// only looks for these modules at the crate level.
include!("attribute_docs.rs");
// Include a number of private modules that exist solely to provide
// the rustdoc documentation for primitive types. Using `include!`
// because rustdoc only looks for these modules at the crate level.
include!("../../core/src/primitive_docs.rs");

// This is required to avoid an unstable error when `restricted-std` is not
// enabled. The use of #![feature(restricted_std)] in rustc-std-workspace-std
Expand Down
Loading
Loading