Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
364475b
Add tests for some cases mentioned in #135589
estebank Jan 16, 2025
3155687
Detect case of missing lifetime in assoc type
estebank Jan 16, 2025
02b8028
On unconstrained lifetime on `impl` block, suggest using it if there'…
estebank Jan 16, 2025
6fcc9f5
Do not suggest introducing lifetime in impl assoc type
estebank Jan 16, 2025
6e22542
test: Add empty line to tests getting new flag in next commit
Muscraft Sep 28, 2025
0a5817a
test: Set diagnostic-width flag for long diagnostic width tests
Muscraft Jul 30, 2025
9c6897b
test: Subtract code_offset from width for ui_testing
Muscraft May 30, 2025
d24ee20
use `fluent_syntax` to parse fluent files
GuillaumeGomez Oct 6, 2025
831cdf3
Fail if no fluent messages were found
GuillaumeGomez Oct 6, 2025
696b6ac
use declarative macro for `#[derive(TryFromU32)]`
fee1-dead Aug 16, 2025
490fd3d
Update books
rustbot Oct 6, 2025
02126ad
Improve diagnostics: replace 'non-inline module' with 'file module' a…
reddevilmidzy Oct 6, 2025
cb06d91
don't panic on extern with just multiple quotes in the name
karolzwolak Oct 6, 2025
7b27b99
Rollup merge of #135602 - estebank:issue-135589, r=Nadrieril
matthiaskrgr Oct 7, 2025
bccc02c
Rollup merge of #145495 - fee1-dead-contrib:push-tynlnktvrmrx, r=Zala…
matthiaskrgr Oct 7, 2025
294c358
Rollup merge of #147165 - Muscraft:subtract-code-offset, r=davidtwco
matthiaskrgr Oct 7, 2025
c917e02
Rollup merge of #147395 - reddevilmidzy:refact-error-msg, r=Kivooeo,j…
matthiaskrgr Oct 7, 2025
cd63ba7
Rollup merge of #147396 - GuillaumeGomez:fluent-tidy-improvements, r=…
matthiaskrgr Oct 7, 2025
56fb84d
Rollup merge of #147407 - rustbot:docs-update, r=ehuss
matthiaskrgr Oct 7, 2025
e06d80f
Rollup merge of #147413 - karolzwolak:extern-multiple-quotes, r=fmease
matthiaskrgr Oct 7, 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
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use rustc_abi::Align;
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods};
use rustc_data_structures::fx::FxIndexMap;
use rustc_index::IndexVec;
use rustc_macros::TryFromU32;
use rustc_middle::ty::TyCtxt;
use rustc_session::RemapFileNameExt;
use rustc_session::config::RemapPathScopeComponents;
Expand All @@ -16,7 +15,7 @@ use tracing::debug;
use crate::common::CodegenCx;
use crate::coverageinfo::llvm_cov;
use crate::coverageinfo::mapgen::covfun::prepare_covfun_record;
use crate::llvm;
use crate::{TryFromU32, llvm};

mod covfun;
mod spans;
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
#![feature(macro_derive)]
#![feature(rustdoc_internals)]
#![feature(slice_as_array)]
#![feature(try_blocks)]
Expand Down Expand Up @@ -65,6 +66,7 @@ mod errors;
mod intrinsic;
mod llvm;
mod llvm_util;
mod macros;
mod mono_item;
mod type_;
mod type_of;
Expand All @@ -74,6 +76,8 @@ mod value;

rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

pub(crate) use macros::TryFromU32;

#[derive(Clone)]
pub struct LlvmCodegenBackend(());

Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@ use std::ptr;

use bitflags::bitflags;
use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t};
use rustc_macros::TryFromU32;

use super::RustString;
use super::debuginfo::{
DIArray, DIBuilder, DIDerivedType, DIDescriptor, DIEnumerator, DIFile, DIFlags,
DIGlobalVariableExpression, DILocation, DISPFlags, DIScope, DISubprogram,
DITemplateTypeParameter, DIType, DebugEmissionKind, DebugNameTableKind,
};
use crate::llvm;
use crate::llvm::MetadataKindId;
use crate::{TryFromU32, llvm};

/// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
/// which has a different ABI from Rust or C++ `bool`.
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_codegen_llvm/src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
macro_rules! TryFromU32 {
derive() (
$(#[$meta:meta])*
$vis:vis enum $Type:ident {
$(
$(#[$varmeta:meta])*
$Variant:ident $(= $discr:expr)?
),* $(,)?
}
) => {
impl ::core::convert::TryFrom<u32> for $Type {
type Error = u32;
#[allow(deprecated)] // Don't warn about deprecated variants.
fn try_from(value: u32) -> ::core::result::Result<$Type, Self::Error> {
$( if value == const { $Type::$Variant as u32 } { return Ok($Type::$Variant) } )*
Err(value)
}
}
}
}

pub(crate) use TryFromU32;
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2021,7 +2021,7 @@ impl HumanEmitter {
if let Some(width) = self.diagnostic_width {
width.saturating_sub(code_offset)
} else if self.ui_testing || cfg!(miri) {
DEFAULT_COLUMN_WIDTH
DEFAULT_COLUMN_WIDTH.saturating_sub(code_offset)
} else {
termize::dimensions()
.map(|(w, _)| w.saturating_sub(code_offset))
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_expand/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ expand_module_file_not_found =
.note = if there is a `mod {$name}` elsewhere in the crate already, import it with `use crate::...` instead
expand_module_in_block =
cannot declare a non-inline module inside a block unless it has a path attribute
.note = maybe `use` the module `{$name}` instead of redeclaring it
cannot declare a file module inside a block unless it has a path attribute
.help = maybe `use` the module `{$name}` instead of redeclaring it
.note = file modules are usually placed outside of blocks, at the top level of the file
expand_module_multiple_candidates =
file for module `{$name}` found at both "{$default_path}" and "{$secondary_path}"
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_expand/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ pub(crate) struct ModuleCircular {

#[derive(Diagnostic)]
#[diag(expand_module_in_block)]
#[note]
pub(crate) struct ModuleInBlock {
#[primary_span]
pub span: Span,
Expand All @@ -273,7 +274,7 @@ pub(crate) struct ModuleInBlock {
}

#[derive(Subdiagnostic)]
#[note(expand_note)]
#[help(expand_help)]
pub(crate) struct ModuleInBlockName {
#[primary_span]
pub span: Span,
Expand Down
24 changes: 23 additions & 1 deletion compiler/rustc_hir_analysis/src/impl_wf_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@

use min_specialization::check_min_specialization;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_errors::codes::*;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_span::ErrorGuaranteed;
use rustc_span::{ErrorGuaranteed, kw};

use crate::constrained_generic_params as cgp;
use crate::errors::UnconstrainedGenericParameter;
Expand Down Expand Up @@ -158,6 +159,27 @@
const_param_note2: false,
});
diag.code(E0207);
for p in &impl_generics.own_params {
if p.name == kw::UnderscoreLifetime {
let span = tcx.def_span(p.def_id);
let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) else {
continue;
};

let (span, sugg) = if &snippet == "'_" {
(span, param.name.to_string())
} else {
(span.shrink_to_hi(), format!("{} ", param.name))
};
diag.span_suggestion_verbose(
span,
"consider using the named lifetime here instead of an implict \

Check failure on line 176 in compiler/rustc_hir_analysis/src/impl_wf_check.rs

View workflow job for this annotation

GitHub Actions / PR - tidy

`implict` should be `implicit`
lifetime",
sugg,
Applicability::MaybeIncorrect,
);
}
}
res = Err(diag.emit());
}
}
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ mod print_attribute;
mod query;
mod serialize;
mod symbols;
mod try_from;
mod type_foldable;
mod type_visitable;
mod visitable;
Expand Down Expand Up @@ -176,14 +175,6 @@ decl_derive!(
applicability)] => diagnostics::subdiagnostic_derive
);

decl_derive! {
[TryFromU32] =>
/// Derives `TryFrom<u32>` for the annotated `enum`, which must have no fields.
/// Each variant maps to the value it would produce under an `as u32` cast.
///
/// The error type is `u32`.
try_from::try_from_u32
}
decl_derive! {
[PrintAttribute] =>
/// Derives `PrintAttribute` for `AttributeKind`.
Expand Down
55 changes: 0 additions & 55 deletions compiler/rustc_macros/src/try_from.rs

This file was deleted.

58 changes: 53 additions & 5 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions,
Applicability, Diag, DiagArgValue, ErrorGuaranteed, IntoDiagArg, StashKey, Suggestions,
pluralize,
};
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
Expand Down Expand Up @@ -377,6 +378,7 @@ enum LifetimeBinderKind {
Function,
Closure,
ImplBlock,
ImplAssocType,
}

impl LifetimeBinderKind {
Expand All @@ -387,6 +389,7 @@ impl LifetimeBinderKind {
PolyTrait => "bound",
WhereBound => "bound",
Item | ConstItem => "item",
ImplAssocType => "associated type",
ImplBlock => "impl block",
Function => "function",
Closure => "closure",
Expand Down Expand Up @@ -1874,9 +1877,13 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
ty: ty.span,
});
} else {
self.r.dcx().emit_err(errors::AnonymousLifetimeNonGatReportError {
lifetime: lifetime.ident.span,
});
let mut err = self.r.dcx().create_err(
errors::AnonymousLifetimeNonGatReportError {
lifetime: lifetime.ident.span,
},
);
self.point_at_impl_lifetimes(&mut err, i, lifetime.ident.span);
err.emit();
}
} else {
self.r.dcx().emit_err(errors::ElidedAnonymousLifetimeReportError {
Expand Down Expand Up @@ -1913,6 +1920,47 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
}

fn point_at_impl_lifetimes(&mut self, err: &mut Diag<'_>, i: usize, lifetime: Span) {
let Some((rib, span)) = self.lifetime_ribs[..i]
.iter()
.rev()
.skip(1)
.filter_map(|rib| match rib.kind {
LifetimeRibKind::Generics { span, kind: LifetimeBinderKind::ImplBlock, .. } => {
Some((rib, span))
}
_ => None,
})
.next()
else {
return;
};
if !rib.bindings.is_empty() {
err.span_label(
span,
format!(
"there {} named lifetime{} specified on the impl block you could use",
if rib.bindings.len() == 1 { "is a" } else { "are" },
pluralize!(rib.bindings.len()),
),
);
if rib.bindings.len() == 1 {
err.span_suggestion_verbose(
lifetime.shrink_to_hi(),
"consider using the lifetime from the impl block",
format!("{} ", rib.bindings.keys().next().unwrap()),
Applicability::MaybeIncorrect,
);
}
} else {
err.span_label(
span,
"you could add a lifetime on the impl block, if the trait or the self type can \
have one",
);
}
}

#[instrument(level = "debug", skip(self))]
fn resolve_elided_lifetime(&mut self, anchor_id: NodeId, span: Span) {
let id = self.r.next_node_id();
Expand Down Expand Up @@ -3352,7 +3400,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
&generics.params,
RibKind::AssocItem,
item.id,
LifetimeBinderKind::Item,
LifetimeBinderKind::ImplAssocType,
generics.span,
|this| {
this.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3168,6 +3168,9 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
{
continue;
}
if let LifetimeBinderKind::ImplAssocType = kind {
continue;
}

if !span.can_be_used_for_suggestions()
&& suggest_note
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2511,9 +2511,11 @@ impl Ident {
}

/// Creates a new ident with the same span and name with leading quote removed, if any.
/// If called on an empty ident, or with name just a single quote, returns an empty ident which is invalid.
/// Calling it on a `'` ident will return an empty ident, which triggers debug assertions.
pub fn without_first_quote(self) -> Ident {
Ident::new(Symbol::intern(self.as_str().trim_start_matches('\'')), self.span)
self.as_str()
.strip_prefix('\'')
.map_or(self, |name| Ident::new(Symbol::intern(name), self.span))
}

/// "Normalize" ident for use in comparisons using "item hygiene".
Expand Down
2 changes: 1 addition & 1 deletion src/doc/reference
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/option_env_unwrap.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set
error: this will panic at run-time if the environment variable doesn't exist at compile-time
--> tests/ui/option_env_unwrap.rs:14:13
|
LL | let _ = option_env!("__Y__do_not_use").unwrap(); // This test only works if you don't have a __Y__do_not_use env variable in your env...
LL | let _ = option_env!("__Y__do_not_use").unwrap(); // This test only works if you don't have a __Y__do_not_use env variable in you...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider using the `env!` macro instead
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ LL | | /// gravida non lacinia at, rhoncus eu lacus.
error: first doc comment paragraph is too long
--> tests/ui/too_long_first_doc_paragraph.rs:65:1
|
LL | / /// Some function. This doc-string paragraph is too long. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lore...
LL | / /// Some function. This doc-string paragraph is too long. Lorem Ipsum is simply dummy text of the printing and typesetting industr...
LL | |
LL | | ///
LL | | /// Here's a second paragraph. It would be preferable to put the details here.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: Undefined Behavior: trying to join an already joined thread
--> tests/fail-dep/concurrency/libc_pthread_join_joined.rs:LL:CC
|
LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
LL | ... assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
Expand Down
Loading
Loading