Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 27 additions & 28 deletions compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,44 +362,43 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
DefinitionSiteHiddenType::new_error(tcx, guar)
});

// Sometimes, when the hidden type is an inference variable, it can happen that
// the hidden type becomes the opaque type itself. In this case, this was an opaque
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
// writeback.
if !rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
// Sometimes, when the hidden type is an inference variable, it can happen that
// the hidden type becomes the opaque type itself. In this case, this was an opaque
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
// writeback.
if let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
hidden_type.ty.skip_binder().kind()
&& def_id == opaque_type_key.def_id.to_def_id()
&& args == opaque_type_key.args
{
continue;
}
}

// Check that all opaque types have the same region parameters if they have the same
// non-region parameters. This is necessary because within the new solver we perform
// various query operations modulo regions, and thus could unsoundly select some impls
// that don't hold.
//
// FIXME(-Znext-solver): This isn't necessary after all. We can remove this check again.
if let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert(
rcx.infcx.tcx.erase_and_anonymize_regions(opaque_type_key),
(opaque_type_key, hidden_type.span),
) && let Some((arg1, arg2)) = std::iter::zip(
prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
)
.find(|(arg1, arg2)| arg1 != arg2)
{
errors.push(DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(
LifetimeMismatchOpaqueParam {
arg: arg1,
prev: arg2,
span: prev_span,
prev_span: hidden_type.span,
},
));
// Check that all opaque types have the same region parameters if they have the same
// non-region parameters. This is necessary because within the new solver we perform
// various query operations modulo regions, and thus could unsoundly select some impls
// that don't hold.
if let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert(
rcx.infcx.tcx.erase_and_anonymize_regions(opaque_type_key),
(opaque_type_key, hidden_type.span),
) && let Some((arg1, arg2)) = std::iter::zip(
prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
)
.find(|(arg1, arg2)| arg1 != arg2)
{
errors.push(DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(
LifetimeMismatchOpaqueParam {
arg: arg1,
prev: arg2,
span: prev_span,
prev_span: hidden_type.span,
},
));
}
}

add_hidden_type(tcx, hidden_types, opaque_type_key.def_id, hidden_type);
}
}
Expand Down
71 changes: 29 additions & 42 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::borrow::Cow;
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};
use std::hash::Hash;
use std::ops::{Deref, DerefMut};
use std::panic;
use std::path::PathBuf;
use std::thread::panicking;

use rustc_ast::attr::version::RustcVersion;
use rustc_error_messages::{DiagArgMap, DiagArgName, DiagArgValue, IntoDiagArg};
use rustc_data_structures::stable_hash::StableHasher;
use rustc_error_messages::{DiagArgMap, DiagArgName, IntoDiagArg};
use rustc_hashes::Hash128;
use rustc_lint_defs::{Applicability, LintExpectationId};
use rustc_macros::{Decodable, Encodable};
use rustc_span::{DUMMY_SP, Span, Spanned, Symbol};
Expand Down Expand Up @@ -305,46 +307,31 @@ impl DiagInner {
}
}

/// Fields used for Hash, and PartialEq trait.
fn keys(
&self,
) -> (
&Level,
&[(DiagMessage, Style)],
&Option<ErrCode>,
&MultiSpan,
&[Subdiag],
&Suggestions,
Vec<(&DiagArgName, &DiagArgValue)>,
&Option<IsLint>,
) {
(
&self.level,
&self.messages,
&self.code,
&self.span,
&self.children,
&self.suggestions,
self.args.iter().collect(),
// omit self.sort_span
&self.is_lint,
// omit self.emitted_at
)
}
}

impl Hash for DiagInner {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
self.keys().hash(state);
}
}

impl PartialEq for DiagInner {
fn eq(&self, other: &Self) -> bool {
self.keys() == other.keys()
/// Hash used to determine if two diagnostics are the same. Used by
/// `DiagCtxtInner::emitted_diagnostics`. Some fields are ignored for the hash.
pub(crate) fn dedup_hash(&self) -> Hash128 {
// Deconstruct to ensure all fields are considered.
let DiagInner {
level,
messages,
code,
lint_id: _, // ignore
span,
children,
suggestions,
args,
sort_span: _, // ignore
is_lint,
long_ty_path: _, // ignore
emitted_at: _, // ignore
} = self;

let hashed_parts =
(level, messages, code, span, children, suggestions, args.as_slice(), is_lint);

let mut hasher = StableHasher::new();
hashed_parts.hash(&mut hasher);
hasher.finish()
}
}

Expand Down
13 changes: 5 additions & 8 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,10 @@ struct DiagCtxtInner {
emitted_diagnostic_codes: FxIndexSet<ErrCode>,

/// This set contains a hash of every diagnostic that has been emitted by
/// this `DiagCtxt`. These hashes is used to avoid emitting the same error
/// twice.
/// this `DiagCtxt`. These hashes are used to avoid emitting the same error
/// twice. (Because we don't store the diagnostics themselves, two
/// different diagnostics with the same hash value will be considered
/// equivalent. Such collisions should be vanishingly rare...)
emitted_diagnostics: FxHashSet<Hash128>,

/// We only want to emit `recursion_depth_exceeding_limit` once per
Expand Down Expand Up @@ -1301,12 +1303,7 @@ impl DiagCtxtInner {
self.emitted_diagnostic_codes.insert(code);
}

let already_emitted = {
let mut hasher = StableHasher::new();
diagnostic.hash(&mut hasher);
let diagnostic_hash = hasher.finish();
!self.emitted_diagnostics.insert(diagnostic_hash)
};
let already_emitted = !self.emitted_diagnostics.insert(diagnostic.dedup_hash());

let is_error = diagnostic.is_error();
let is_lint = diagnostic.is_lint.is_some();
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,7 @@ declare_lint_pass!(NonShorthandFieldPatterns => [NON_SHORTHAND_FIELD_PATTERNS]);

impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
fn check_pat(&mut self, cx: &LateContext<'_>, pat: &hir::Pat<'_>) {
// The result shouldn't be tainted, otherwise it will cause ICE.
if let PatKind::Struct(ref qpath, field_pats, _) = pat.kind
&& cx.typeck_results().tainted_by_errors.is_none()
{
if let PatKind::Struct(ref qpath, field_pats, _) = pat.kind {
let variant = cx
.typeck_results()
.pat_ty(pat)
Expand Down
21 changes: 19 additions & 2 deletions compiler/rustc_lint/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,15 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
// The body and typeck results are also set in `visit_fn`.
// Only fetch the results if this is for a new body.
if old_enclosing_body != Some(body_id) && !self.actually_rustdoc {
self.context.typeck_results = Some(self.context.tcx.typeck_body(body_id));
let typeck_results = self.context.tcx.typeck_body(body_id);

// To avoid ICE, skip visiting the body if the typeck_results is tainted.
if typeck_results.tainted_by_errors.is_some() {
self.context.enclosing_body = old_enclosing_body;
self.context.typeck_results = old_typeck_results;
return;
}
self.context.typeck_results = Some(typeck_results);
}

let body = self.context.tcx.hir_body(body_id);
Expand Down Expand Up @@ -189,7 +197,16 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
let old_enclosing_body = self.context.enclosing_body.replace(body_id);
let old_typeck_results = self.context.typeck_results;
if !self.actually_rustdoc {
self.context.typeck_results = Some(self.context.tcx.typeck_body(body_id));
let typeck_results = self.context.tcx.typeck_body(body_id);

// To avoid ICE, skip visiting the body if the typeck_results is tainted.
if typeck_results.tainted_by_errors.is_some() {
self.context.enclosing_body = old_enclosing_body;
self.context.typeck_results = old_typeck_results;
return;
}

self.context.typeck_results = Some(typeck_results);
}
let body = self.context.tcx.hir_body(body_id);
lint_callback!(self, check_fn, fk, decl, body, span, id);
Expand Down
15 changes: 11 additions & 4 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,10 +678,13 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {

if let Some(def_id) = is_const_pat_that_looks_like_binding(self.tcx, pat) {
let span = self.tcx.def_span(def_id);
let variable = self.tcx.item_name(def_id).to_string();
let name = self.tcx.item_name(def_id);
// When we encounter a constant as the binding name, point at the `const` definition.
interpreted_as_const = Some(InterpretedAsConst { span, variable: variable.clone() });
interpreted_as_const_sugg = Some(InterpretedAsConstSugg { span: pat.span, variable });
interpreted_as_const =
Some(InterpretedAsConst { span, variable: name.to_ident_string() });
// The suggested name is suffixed, so it is never a keyword and never needs `r#`.
interpreted_as_const_sugg =
Some(InterpretedAsConstSugg { span: pat.span, variable: name.to_string() });
} else if let PatKind::Constant { .. } = pat.kind
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
{
Expand Down Expand Up @@ -1231,7 +1234,11 @@ fn is_const_pat_that_looks_like_binding<'tcx>(tcx: TyCtxt<'tcx>, pat: &Pat<'tcx>
// `::` namespace separators or other non-identifier characters.
if let ty::AliasConstKind::Free { def_id } = pat.extra.as_deref()?.expanded_const?
&& let Ok(snippet) = tcx.sess.source_map().span_to_snippet(pat.span)
&& snippet.chars().all(|c| c.is_alphanumeric() || c == '_')
&& snippet
.strip_prefix("r#")
.unwrap_or(&snippet)
.chars()
.all(|c| c.is_alphanumeric() || c == '_')
{
Some(def_id)
} else {
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_mir_transform/src/dead_store_elimination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
loc,
);

// The logic in LivenessTransferFunction isn't quite what we need; it ignores call
// destinations that are just locals because they are killed by the call, which makes
// it eligible to be moved-from in the argument list. That's backwards.
if !destination.is_indirect() {
state.insert(destination.local);
}

for (index, arg) in args.iter().map(|a| &a.node).enumerate().rev() {
if let Operand::Copy(place) = *arg
&& !place.is_indirect()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1494,6 +1494,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) {
// FIXME(field_projections): We should not use `evaluate_obligation` in
// the trait solver. Doing so means we don't track overflow and cycles properly
// encountering query cycles instead.
if let ty::Adt(def, args) = obligation.predicate.self_ty().skip_binder().kind()
&& let Some(FieldInfo { base, ty, .. }) =
def.field_representing_type_info(self.tcx(), args)
Expand Down
1 change: 0 additions & 1 deletion library/alloc/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,6 @@ pub const fn handle_alloc_error(layout: Layout) -> ! {

#[cfg(not(no_global_oom_handling))]
#[doc(hidden)]
#[allow(unused_attributes)]
#[unstable(feature = "alloc_internals", issue = "none")]
pub mod __alloc_error_handler {
// called via generated `__rust_alloc_error_handler` if there is no
Expand Down
1 change: 0 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@

#![allow(unused_features)]
#![allow(incomplete_features)]
#![allow(unused_attributes)]
#![expect(clippy::partialeq_ne_impl, reason = "we need to implement ne for a lot of alloc types")]
#![stable(feature = "alloc", since = "1.36.0")]
#![doc(
Expand Down
1 change: 0 additions & 1 deletion library/alloctests/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![cfg(test)]
#![allow(unused_attributes)]
#![unstable(feature = "alloctests", issue = "none")]
#![no_std]
// Lints:
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/alloc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub use self::layout::Layout;
note = "Name does not follow std convention, use LayoutError",
suggestion = "LayoutError"
)]
#[allow(deprecated, deprecated_in_future)]
#[allow(deprecated)]
pub use self::layout::LayoutErr;
#[stable(feature = "alloc_layout_error", since = "1.50.0")]
pub use self::layout::LayoutError;
Expand Down
1 change: 0 additions & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,6 @@ pub mod primitive;
unused_imports,
unsafe_op_in_unsafe_fn,
ambiguous_glob_reexports,
deprecated_in_future,
unreachable_pub,
// FIXME: stdach is a submodule so clippy lints should be fixed (and ideally enforced) there
clippy::all,
Expand Down
3 changes: 0 additions & 3 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2485,7 +2485,6 @@ macro_rules! int_impl {
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[allow(unused_attributes)]
#[inline]
pub const fn wrapping_abs(self) -> Self {
if self.is_negative() {
Expand Down Expand Up @@ -2978,7 +2977,6 @@ macro_rules! int_impl {
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[allow(unused_attributes)]
pub const fn overflowing_neg(self) -> (Self, bool) {
if intrinsics::unlikely(self == Self::MIN) {
(Self::MIN, true)
Expand Down Expand Up @@ -3630,7 +3628,6 @@ macro_rules! int_impl {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
#[allow(unused_attributes)]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/panic/panic_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl<'a> PanicInfo<'a> {
/// [`std::panic::PanicHookInfo::payload`]: ../../std/panic/struct.PanicHookInfo.html#method.payload
#[deprecated(since = "1.81.0", note = "this never returns anything useful")]
#[stable(feature = "panic_hooks", since = "1.10.0")]
#[allow(deprecated, deprecated_in_future)]
#[allow(deprecated)]
pub fn payload(&self) -> &(dyn crate::any::Any + Send) {
struct NoPayload;
&NoPayload
Expand Down
1 change: 0 additions & 1 deletion library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,6 @@ impl str {
#[rustc_const_stable(feature = "str_as_bytes", since = "1.39.0")]
#[must_use]
#[inline(always)]
#[allow(unused_attributes)]
pub const fn as_bytes(&self) -> &[u8] {
// SAFETY: const sound because we transmute two types with the same layout
unsafe { mem::transmute(self) }
Expand Down
1 change: 0 additions & 1 deletion library/std/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,6 @@ pub fn rust_oom(layout: Layout) -> ! {

#[cfg(not(test))]
#[doc(hidden)]
#[allow(unused_attributes)]
#[unstable(feature = "alloc_internals", issue = "none")]
pub mod __default_lib_allocator {
use super::Layout;
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ impl fmt::Display for JoinPathsError {

#[stable(feature = "env", since = "1.0.0")]
impl Error for JoinPathsError {
#[allow(deprecated, deprecated_in_future)]
#[allow(deprecated)]
fn description(&self) -> &str {
self.inner.description()
}
Expand Down
Loading
Loading