Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
400e687
Bump unicode_data to version 17.0.0
Marcondiro Sep 8, 2025
83a99aa
Bump unicode printable to version 17.0.0
Marcondiro Sep 9, 2025
e1ae7b7
tests: Check error when struct from wrong crate version is used for impl
Enselic Sep 22, 2025
141cada
compiler: Hint at multiple crate versions if trait impl is for wrong ADT
Enselic Sep 22, 2025
d834935
Fix atan2 inaccuracy in documentation
DimitriiTrater Sep 11, 2025
d615d2f
std: call WinSock cleanup function directly instead of through its re…
joboet Sep 30, 2025
eba1416
std: improve internal socket functions
joboet Sep 30, 2025
aa1263e
std: add missing unsafe blocks
joboet Sep 30, 2025
3534594
std: merge address family computation
joboet Sep 30, 2025
08b4641
add CloneFromCell and Cell::get_cloned
Qelxiros Aug 20, 2025
99550fb
Return to needs-llvm-components being info-only
workingjubilee Oct 2, 2025
181b302
Move `DirectiveLine` into its own submodule
Zalathar Oct 3, 2025
c368f9a
Allow easy extraction of name/value from a `DirectiveLine`
Zalathar Oct 2, 2025
e73c221
Use new `DirectiveLine` features in directive parsing
Zalathar Oct 2, 2025
1485e78
Document fully-qualified syntax in `as`' keyword doc
fpdotmonkey Jun 18, 2025
a9ab29c
add mem::conjure_zst
Qelxiros Sep 12, 2025
fd96a78
Add documentation about unwinding to wasm targets
alexcrichton Oct 3, 2025
55aeb17
Do not assert that a change in global cache only happens when concurrent
jackh726 Oct 2, 2025
c721fa2
interpret #[used] as #[used(compiler)] on illumos
iximeow Sep 28, 2025
12cfad9
update autodiff batching test
ZuseZ4 Oct 3, 2025
422b914
Fix top level ui tests check in tidy
chenyukang Oct 4, 2025
1782456
Rollup merge of #142670 - fpdotmonkey:doc/as-fully-qualified-syntax, …
Zalathar Oct 4, 2025
0a52bf7
Rollup merge of #145685 - Qelxiros:cell_get_cloned, r=programmerjake,…
Zalathar Oct 4, 2025
90ea19e
Rollup merge of #146330 - Marcondiro:unicode-17, r=Manishearth
Zalathar Oct 4, 2025
4d89574
Rollup merge of #146451 - DimitriiTrater:atan2_correctness_docs, r=tg…
Zalathar Oct 4, 2025
c005c5d
Rollup merge of #146479 - Qelxiros:mem_conjure_zst, r=scottmcm,tgross35
Zalathar Oct 4, 2025
bfdcdb6
Rollup merge of #146874 - Enselic:multiple-adt-versions, r=jieyouxu
Zalathar Oct 4, 2025
dbc85e5
Rollup merge of #147117 - iximeow:ixi/illumos-used-attr, r=Noratrieb
Zalathar Oct 4, 2025
63080e4
Rollup merge of #147190 - joboet:sys-net-cleanup, r=hkBst,tgross35
Zalathar Oct 4, 2025
091533b
Rollup merge of #147251 - jackh726:global-cache-non-concurrent-change…
Zalathar Oct 4, 2025
4e9cab8
Rollup merge of #147280 - workingjubilee:you-can-put-your-gcc-in-my-l…
Zalathar Oct 4, 2025
b122941
Rollup merge of #147288 - Zalathar:directive, r=jieyouxu
Zalathar Oct 4, 2025
8ba1a4c
Rollup merge of #147309 - alexcrichton:wasm-unwinding-docs, r=jieyouxu
Zalathar Oct 4, 2025
05053ad
Rollup merge of #147315 - ZuseZ4:fix-ad-batching-test, r=jieyouxu
Zalathar Oct 4, 2025
ee8b684
Rollup merge of #147323 - chenyukang:yukang-fix-tidy-check, r=jieyouxu
Zalathar Oct 4, 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
36 changes: 28 additions & 8 deletions compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for NoMangleParser {
pub(crate) struct UsedParser {
first_compiler: Option<Span>,
first_linker: Option<Span>,
first_default: Option<Span>,
}

// A custom `AttributeParser` is used rather than a Simple attribute parser because
Expand All @@ -382,7 +383,7 @@ impl<S: Stage> AttributeParser<S> for UsedParser {
template!(Word, List: &["compiler", "linker"]),
|group: &mut Self, cx, args| {
let used_by = match args {
ArgParser::NoArgs => UsedBy::Linker,
ArgParser::NoArgs => UsedBy::Default,
ArgParser::List(list) => {
let Some(l) = list.single() else {
cx.expected_single_argument(list.span);
Expand Down Expand Up @@ -423,12 +424,29 @@ impl<S: Stage> AttributeParser<S> for UsedParser {
ArgParser::NameValue(_) => return,
};

let attr_span = cx.attr_span;

// `#[used]` is interpreted as `#[used(linker)]` (though depending on target OS the
// circumstances are more complicated). While we're checking `used_by`, also report
// these cross-`UsedBy` duplicates to warn.
let target = match used_by {
UsedBy::Compiler => &mut group.first_compiler,
UsedBy::Linker => &mut group.first_linker,
UsedBy::Linker => {
if let Some(prev) = group.first_default {
cx.warn_unused_duplicate(prev, attr_span);
return;
}
&mut group.first_linker
}
UsedBy::Default => {
if let Some(prev) = group.first_linker {
cx.warn_unused_duplicate(prev, attr_span);
return;
}
&mut group.first_default
}
};

let attr_span = cx.attr_span;
if let Some(prev) = *target {
cx.warn_unused_duplicate(prev, attr_span);
} else {
Expand All @@ -440,11 +458,13 @@ impl<S: Stage> AttributeParser<S> for UsedParser {
AllowedTargets::AllowList(&[Allow(Target::Static), Warn(Target::MacroCall)]);

fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
// Ratcheting behaviour, if both `linker` and `compiler` are specified, use `linker`
Some(match (self.first_compiler, self.first_linker) {
(_, Some(span)) => AttributeKind::Used { used_by: UsedBy::Linker, span },
(Some(span), _) => AttributeKind::Used { used_by: UsedBy::Compiler, span },
(None, None) => return None,
// If a specific form of `used` is specified, it takes precedence over generic `#[used]`.
// If both `linker` and `compiler` are specified, use `linker`.
Some(match (self.first_compiler, self.first_linker, self.first_default) {
(_, Some(span), _) => AttributeKind::Used { used_by: UsedBy::Linker, span },
(Some(span), _, _) => AttributeKind::Used { used_by: UsedBy::Compiler, span },
(_, _, Some(span)) => AttributeKind::Used { used_by: UsedBy::Default, span },
(None, None, None) => return None,
})
}
}
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,19 @@ fn process_builtin_attrs(
AttributeKind::Used { used_by, .. } => match used_by {
UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER,
UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER,
UsedBy::Default => {
let used_form = if tcx.sess.target.os == "illumos" {
// illumos' `ld` doesn't support a section header that would represent
// `#[used(linker)]`, see
// https://github.com/rust-lang/rust/issues/146169. For that target,
// downgrade as if `#[used(compiler)]` was requested and hope for the
// best.
CodegenFnAttrFlags::USED_COMPILER
} else {
CodegenFnAttrFlags::USED_LINKER
};
codegen_fn_attrs.flags |= used_form;
}
},
AttributeKind::FfiConst(_) => {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,13 @@ impl Deprecation {
}

/// There are three valid forms of the attribute:
/// `#[used]`, which is semantically equivalent to `#[used(linker)]` except that the latter is currently unstable.
/// `#[used]`, which is equivalent to `#[used(linker)]` on targets that support it, but `#[used(compiler)]` if not.
/// `#[used(compiler)]`
/// `#[used(linker)]`
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(HashStable_Generic, PrintAttribute)]
pub enum UsedBy {
Default,
Compiler,
Linker,
}
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
from_entry(entry)
}

fn evaluation_is_concurrent(&self) -> bool {
self.sess.threads() > 1
fn assert_evaluation_is_concurrent(&self) {
// Turns out, the assumption for this function isn't perfect.
// See trait-system-refactor-initiative#234.
}

fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
span,
leaf_trait_predicate,
);
self.note_version_mismatch(&mut err, leaf_trait_predicate);
self.note_trait_version_mismatch(&mut err, leaf_trait_predicate);
self.note_adt_version_mismatch(&mut err, leaf_trait_predicate);
self.suggest_remove_await(&obligation, &mut err);
self.suggest_derive(&obligation, &mut err, leaf_trait_predicate);

Expand Down Expand Up @@ -2424,7 +2425,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
/// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
/// with the same path as `trait_ref`, a help message about
/// a probable version mismatch is added to `err`
fn note_version_mismatch(
fn note_trait_version_mismatch(
&self,
err: &mut Diag<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>,
Expand Down Expand Up @@ -2464,15 +2465,87 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
impl_spans,
format!("trait impl{} with same name found", pluralize!(trait_impls.len())),
);
let trait_crate = self.tcx.crate_name(trait_with_same_path.krate);
let crate_msg =
format!("perhaps two different versions of crate `{trait_crate}` are being used?");
err.note(crate_msg);
self.note_two_crate_versions(trait_with_same_path, err);
suggested = true;
}
suggested
}

fn note_two_crate_versions(&self, did: DefId, err: &mut Diag<'_>) {
let crate_name = self.tcx.crate_name(did.krate);
let crate_msg =
format!("perhaps two different versions of crate `{crate_name}` are being used?");
err.note(crate_msg);
}

fn note_adt_version_mismatch(
&self,
err: &mut Diag<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>,
) {
let ty::Adt(impl_self_def, _) = trait_pred.self_ty().skip_binder().peel_refs().kind()
else {
return;
};

let impl_self_did = impl_self_def.did();

// We only want to warn about different versions of a dependency.
// If no dependency is involved, bail.
if impl_self_did.krate == LOCAL_CRATE {
return;
}

let impl_self_path = self.comparable_path(impl_self_did);
let impl_self_crate_name = self.tcx.crate_name(impl_self_did.krate);
let similar_items: UnordSet<_> = self
.tcx
.visible_parent_map(())
.items()
.filter_map(|(&item, _)| {
// If we found ourselves, ignore.
if impl_self_did == item {
return None;
}
// We only want to warn about different versions of a dependency.
// Ignore items from our own crate.
if item.krate == LOCAL_CRATE {
return None;
}
// We want to warn about different versions of a dependency.
// So make sure the crate names are the same.
if impl_self_crate_name != self.tcx.crate_name(item.krate) {
return None;
}
// Filter out e.g. constructors that often have the same path
// str as the relevant ADT.
if !self.tcx.def_kind(item).is_adt() {
return None;
}
let path = self.comparable_path(item);
// We don't know if our item or the one we found is the re-exported one.
// Check both cases.
let is_similar = path.ends_with(&impl_self_path) || impl_self_path.ends_with(&path);
is_similar.then_some((item, path))
})
.collect();

let mut similar_items =
similar_items.into_items().into_sorted_stable_ord_by_key(|(_, path)| path);
similar_items.dedup();

for (similar_item, _) in similar_items {
err.span_help(self.tcx.def_span(similar_item), "item with same name found");
self.note_two_crate_versions(similar_item, err);
}
}

/// Add a `::` prefix when comparing paths so that paths with just one item
/// like "Foo" does not equal the end of "OtherFoo".
fn comparable_path(&self, did: DefId) -> String {
format!("::{}", self.tcx.def_path_str(did))
}

/// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the
/// `trait_ref`.
///
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_type_ir/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ pub trait Interner:
from_entry: impl FnOnce(&CanonicalParamEnvCacheEntry<Self>) -> R,
) -> R;

fn evaluation_is_concurrent(&self) -> bool;
/// Useful for testing. If a cache entry is replaced, this should
/// (in theory) only happen when concurrent.
fn assert_evaluation_is_concurrent(&self);

fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T;

Expand Down Expand Up @@ -567,7 +569,7 @@ impl<I: Interner> search_graph::Cx for I {
fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
I::with_global_cache(self, f)
}
fn evaluation_is_concurrent(&self) -> bool {
self.evaluation_is_concurrent()
fn assert_evaluation_is_concurrent(&self) {
self.assert_evaluation_is_concurrent()
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_type_ir/src/search_graph/global_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ impl<X: Cx> GlobalCache<X> {
let with_overflow = WithOverflow { nested_goals, result };
let prev = entry.with_overflow.insert(required_depth, with_overflow);
if let Some(prev) = &prev {
assert!(cx.evaluation_is_concurrent());
cx.assert_evaluation_is_concurrent();
assert_eq!(cx.get_tracked(&prev.result), evaluation_result.result);
}
} else {
let prev = entry.success.replace(Success { required_depth, nested_goals, result });
if let Some(prev) = &prev {
assert!(cx.evaluation_is_concurrent());
cx.assert_evaluation_is_concurrent();
assert_eq!(cx.get_tracked(&prev.result), evaluation_result.result);
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/search_graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub trait Cx: Copy {

fn with_global_cache<R>(self, f: impl FnOnce(&mut GlobalCache<Self>) -> R) -> R;

fn evaluation_is_concurrent(&self) -> bool;
fn assert_evaluation_is_concurrent(&self);
}

pub trait Delegate: Sized {
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
#![feature(bstr)]
#![feature(bstr_internals)]
#![feature(cast_maybe_uninit)]
#![feature(cell_get_cloned)]
#![feature(char_internals)]
#![feature(char_max_len)]
#![feature(clone_to_uninit)]
Expand Down
10 changes: 9 additions & 1 deletion library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@
#![stable(feature = "rust1", since = "1.0.0")]

use core::any::Any;
use core::cell::Cell;
use core::cell::{Cell, CloneFromCell};
#[cfg(not(no_global_oom_handling))]
use core::clone::CloneToUninit;
use core::clone::UseCloned;
Expand Down Expand Up @@ -340,6 +340,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Rc<U, A>> for
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T> {}

// SAFETY: `Rc::clone` doesn't access any `Cell`s which could contain the `Rc` being cloned.
#[unstable(feature = "cell_get_cloned", issue = "145329")]
unsafe impl<T: ?Sized> CloneFromCell for Rc<T> {}

impl<T: ?Sized> Rc<T> {
#[inline]
unsafe fn from_inner(ptr: NonNull<RcInner<T>>) -> Self {
Expand Down Expand Up @@ -3013,6 +3017,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Weak<U, A>> f
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}

// SAFETY: `Weak::clone` doesn't access any `Cell`s which could contain the `Weak` being cloned.
#[unstable(feature = "cell_get_cloned", issue = "145329")]
unsafe impl<T: ?Sized> CloneFromCell for Weak<T> {}

impl<T> Weak<T> {
/// Constructs a new `Weak<T>`, without allocating any memory.
/// Calling [`upgrade`] on the return value always gives [`None`].
Expand Down
9 changes: 9 additions & 0 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! `#[cfg(target_has_atomic = "ptr")]`.
use core::any::Any;
use core::cell::CloneFromCell;
#[cfg(not(no_global_oom_handling))]
use core::clone::CloneToUninit;
use core::clone::UseCloned;
Expand Down Expand Up @@ -281,6 +282,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Arc<U, A>> fo
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Arc<U>> for Arc<T> {}

// SAFETY: `Arc::clone` doesn't access any `Cell`s which could contain the `Arc` being cloned.
#[unstable(feature = "cell_get_cloned", issue = "145329")]
unsafe impl<T: ?Sized> CloneFromCell for Arc<T> {}

impl<T: ?Sized> Arc<T> {
unsafe fn from_inner(ptr: NonNull<ArcInner<T>>) -> Self {
unsafe { Self::from_inner_in(ptr, Global) }
Expand Down Expand Up @@ -356,6 +361,10 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Weak<U, A>> f
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}

// SAFETY: `Weak::clone` doesn't access any `Cell`s which could contain the `Weak` being cloned.
#[unstable(feature = "cell_get_cloned", issue = "145329")]
unsafe impl<T: ?Sized> CloneFromCell for Weak<T> {}

#[stable(feature = "arc_weak", since = "1.4.0")]
impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down
Loading
Loading