Skip to content

Commit 222c99b

Browse files
committed
Auto merge of rust-lang#131601 - matthiaskrgr:rollup-iaai3u5, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#130870 (Add suggestion for removing invalid path sep `::` in fn def) - rust-lang#131233 (std: fix stdout-before-main) - rust-lang#131239 (Don't assume traits used as type are trait objs in 2021 edition) - rust-lang#131277 (Handle `clippy` cases of `rustc::potential_query_instability` lint) - rust-lang#131567 (Emit an error for unstable attributes that reference already stable features) - rust-lang#131585 (compiletest: Remove the one thing that was checking a directive's `original_line`) - rust-lang#131590 (yeet some clones) - rust-lang#131597 (Take a display name for `tool_check_step!`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 8f8bee4 + 8de5429 commit 222c99b

File tree

91 files changed

+868
-779
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+868
-779
lines changed

compiler/rustc_borrowck/src/nll.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
165165
universe_causes,
166166
type_tests,
167167
liveness_constraints,
168-
elements.clone(),
168+
elements,
169169
);
170170

171171
// If requested: dump NLL facts, and run legacy polonius analysis.

compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ pub(crate) fn expand_deriving_smart_ptr(
312312
impl_generics.params.insert(pointee_param_idx + 1, extra_param);
313313

314314
// Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`.
315-
let gen_args = vec![GenericArg::Type(alt_self_type.clone())];
315+
let gen_args = vec![GenericArg::Type(alt_self_type)];
316316
add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone());
317317
add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args);
318318
}

compiler/rustc_data_structures/src/unhash.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::hash::{BuildHasherDefault, Hasher};
33

44
pub type UnhashMap<K, V> = HashMap<K, V, BuildHasherDefault<Unhasher>>;
55
pub type UnhashSet<V> = HashSet<V, BuildHasherDefault<Unhasher>>;
6+
pub type UnindexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<Unhasher>>;
67

78
/// This no-op hasher expects only a single `write_u64` call. It's intended for
89
/// map keys that already have hash-like quality, like `Fingerprint`.

compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs

+25-28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_ast::TraitObjectSyntax;
22
use rustc_errors::codes::*;
3-
use rustc_errors::{Diag, EmissionGuarantee, StashKey};
3+
use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed, StashKey, Suggestions};
44
use rustc_hir as hir;
55
use rustc_hir::def::{DefKind, Res};
66
use rustc_lint_defs::Applicability;
@@ -15,13 +15,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
1515
///
1616
/// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`.
1717
/// In edition 2021 and onward we emit a hard error for them.
18-
pub(super) fn prohibit_or_lint_bare_trait_object_ty(&self, self_ty: &hir::Ty<'_>) {
18+
pub(super) fn prohibit_or_lint_bare_trait_object_ty(
19+
&self,
20+
self_ty: &hir::Ty<'_>,
21+
) -> Option<ErrorGuaranteed> {
1922
let tcx = self.tcx();
2023

2124
let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
2225
self_ty.kind
2326
else {
24-
return;
27+
return None;
2528
};
2629

2730
let in_path = match tcx.parent_hir_node(self_ty.hir_id) {
@@ -70,8 +73,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
7073
}
7174

7275
if self_ty.span.edition().at_least_rust_2021() {
73-
let msg = "trait objects must include the `dyn` keyword";
74-
let label = "add `dyn` keyword before this trait";
76+
let msg = "expected a type, found a trait";
77+
let label = "you can add the `dyn` keyword if you want a trait object";
7578
let mut diag =
7679
rustc_errors::struct_span_code_err!(self.dcx(), self_ty.span, E0782, "{}", msg);
7780
if self_ty.span.can_be_used_for_suggestions()
@@ -83,7 +86,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
8386
// Check if the impl trait that we are considering is an impl of a local trait.
8487
self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag);
8588
self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
86-
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
89+
// In case there is an associate type with the same name
90+
// Add the suggestion to this error
91+
if let Some(mut sugg) =
92+
tcx.dcx().steal_non_err(self_ty.span, StashKey::AssociatedTypeSuggestion)
93+
&& let Suggestions::Enabled(ref mut s1) = diag.suggestions
94+
&& let Suggestions::Enabled(ref mut s2) = sugg.suggestions
95+
{
96+
s1.append(s2);
97+
sugg.cancel();
98+
}
99+
diag.stash(self_ty.span, StashKey::TraitMissingMethod)
87100
} else {
88101
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| {
89102
lint.primary_message("trait objects without an explicit `dyn` are deprecated");
@@ -96,6 +109,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
96109
}
97110
self.maybe_suggest_blanket_trait_impl(self_ty, lint);
98111
});
112+
None
99113
}
100114
}
101115

@@ -174,41 +188,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
174188
// 1. Independent functions
175189
// 2. Functions inside trait blocks
176190
// 3. Functions inside impl blocks
177-
let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) {
191+
let (sig, generics) = match tcx.hir_node_by_def_id(parent_id) {
178192
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, generics, _), .. }) => {
179-
(sig, generics, None)
193+
(sig, generics)
180194
}
181195
hir::Node::TraitItem(hir::TraitItem {
182196
kind: hir::TraitItemKind::Fn(sig, _),
183197
generics,
184-
owner_id,
185198
..
186-
}) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))),
199+
}) => (sig, generics),
187200
hir::Node::ImplItem(hir::ImplItem {
188201
kind: hir::ImplItemKind::Fn(sig, _),
189202
generics,
190-
owner_id,
191203
..
192-
}) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))),
204+
}) => (sig, generics),
193205
_ => return false,
194206
};
195207
let Ok(trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else {
196208
return false;
197209
};
198210
let impl_sugg = vec![(self_ty.span.shrink_to_lo(), "impl ".to_string())];
199-
let mut is_downgradable = true;
200-
201211
// Check if trait object is safe for suggesting dynamic dispatch.
202212
let is_dyn_compatible = match self_ty.kind {
203213
hir::TyKind::TraitObject(objects, ..) => {
204214
objects.iter().all(|(o, _)| match o.trait_ref.path.res {
205-
Res::Def(DefKind::Trait, id) => {
206-
if Some(id) == owner {
207-
// For recursive traits, don't downgrade the error. (#119652)
208-
is_downgradable = false;
209-
}
210-
tcx.is_dyn_compatible(id)
211-
}
215+
Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id),
212216
_ => false,
213217
})
214218
}
@@ -255,9 +259,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
255259
suggestion,
256260
Applicability::MachineApplicable,
257261
);
258-
} else if is_downgradable {
259-
// We'll emit the dyn-compatibility error already, with a structured suggestion.
260-
diag.downgrade_to_delayed_bug();
261262
}
262263
return true;
263264
}
@@ -281,10 +282,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
281282
);
282283
if !is_dyn_compatible {
283284
diag.note(format!("`{trait_name}` it is dyn-incompatible, so it can't be `dyn`"));
284-
if is_downgradable {
285-
// We'll emit the dyn-compatibility error already, with a structured suggestion.
286-
diag.downgrade_to_delayed_bug();
287-
}
288285
} else {
289286
// No ampersand in suggestion if it's borrowed already
290287
let (dyn_str, paren_dyn_str) =

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -2063,13 +2063,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
20632063
)
20642064
}
20652065
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
2066-
self.prohibit_or_lint_bare_trait_object_ty(hir_ty);
2067-
2068-
let repr = match repr {
2069-
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
2070-
TraitObjectSyntax::DynStar => ty::DynStar,
2071-
};
2072-
self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
2066+
if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) {
2067+
// Don't continue with type analysis if the `dyn` keyword is missing
2068+
// It generates confusing errors, especially if the user meant to use another
2069+
// keyword like `impl`
2070+
Ty::new_error(tcx, guar)
2071+
} else {
2072+
let repr = match repr {
2073+
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
2074+
TraitObjectSyntax::DynStar => ty::DynStar,
2075+
};
2076+
self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
2077+
}
20732078
}
20742079
// If we encounter a fully qualified path with RTN generics, then it must have
20752080
// *not* gone through `lower_ty_maybe_return_type_notation`, and therefore

compiler/rustc_parse/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,9 @@ parse_invalid_meta_item = expected unsuffixed literal, found `{$token}`
422422
423423
parse_invalid_offset_of = offset_of expects dot-separated field and variant names
424424
425+
parse_invalid_path_sep_in_fn_definition = invalid path separator in function definition
426+
.suggestion = remove invalid path separator
427+
425428
parse_invalid_unicode_escape = invalid unicode character escape
426429
.label = invalid escape
427430
.help = unicode escape must {$surrogate ->

compiler/rustc_parse/src/errors.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,14 @@ pub(crate) struct MissingFnParams {
17551755
pub span: Span,
17561756
}
17571757

1758+
#[derive(Diagnostic)]
1759+
#[diag(parse_invalid_path_sep_in_fn_definition)]
1760+
pub(crate) struct InvalidPathSepInFnDefinition {
1761+
#[primary_span]
1762+
#[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
1763+
pub span: Span,
1764+
}
1765+
17581766
#[derive(Diagnostic)]
17591767
#[diag(parse_missing_trait_in_trait_impl)]
17601768
pub(crate) struct MissingTraitInTraitImpl {

compiler/rustc_parse/src/parser/generics.rs

+7
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,13 @@ impl<'a> Parser<'a> {
269269
/// | ( < lifetimes , typaramseq ( , )? > )
270270
/// where typaramseq = ( typaram ) | ( typaram , typaramseq )
271271
pub(super) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
272+
// invalid path separator `::` in function definition
273+
// for example `fn invalid_path_separator::<T>() {}`
274+
if self.eat_noexpect(&token::PathSep) {
275+
self.dcx()
276+
.emit_err(errors::InvalidPathSepInFnDefinition { span: self.prev_token.span });
277+
}
278+
272279
let span_lo = self.token.span;
273280
let (params, span) = if self.eat_lt() {
274281
let params = self.parse_generic_params()?;

compiler/rustc_passes/messages.ftl

+6
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,12 @@ passes_unrecognized_repr_hint =
739739
unrecognized representation hint
740740
.help = valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
741741
742+
passes_unstable_attr_for_already_stable_feature =
743+
can't mark as unstable using an already stable feature
744+
.label = this feature is already stable
745+
.item = the stability attribute annotates this item
746+
.help = consider removing the attribute
747+
742748
passes_unused =
743749
unused attribute
744750
.suggestion = remove this attribute

compiler/rustc_passes/src/errors.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,17 @@ pub(crate) struct CannotStabilizeDeprecated {
14801480
pub item_sp: Span,
14811481
}
14821482

1483+
#[derive(Diagnostic)]
1484+
#[diag(passes_unstable_attr_for_already_stable_feature)]
1485+
pub(crate) struct UnstableAttrForAlreadyStableFeature {
1486+
#[primary_span]
1487+
#[label]
1488+
#[help]
1489+
pub span: Span,
1490+
#[label(passes_item)]
1491+
pub item_sp: Span,
1492+
}
1493+
14831494
#[derive(Diagnostic)]
14841495
#[diag(passes_missing_stability_attr)]
14851496
pub(crate) struct MissingStabilityAttr<'a> {

compiler/rustc_passes/src/stability.rs

+16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_attr::{
1010
};
1111
use rustc_data_structures::fx::FxIndexMap;
1212
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
13+
use rustc_feature::ACCEPTED_FEATURES;
1314
use rustc_hir as hir;
1415
use rustc_hir::def::{DefKind, Res};
1516
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId};
@@ -246,12 +247,27 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
246247
}
247248
}
248249

250+
if let Stability { level: Unstable { .. }, feature } = stab {
251+
if ACCEPTED_FEATURES.iter().find(|f| f.name == feature).is_some() {
252+
self.tcx
253+
.dcx()
254+
.emit_err(errors::UnstableAttrForAlreadyStableFeature { span, item_sp });
255+
}
256+
}
249257
if let Stability { level: Unstable { implied_by: Some(implied_by), .. }, feature } =
250258
stab
251259
{
252260
self.index.implications.insert(implied_by, feature);
253261
}
254262

263+
if let Some(ConstStability { level: Unstable { .. }, feature, .. }) = const_stab {
264+
if ACCEPTED_FEATURES.iter().find(|f| f.name == feature).is_some() {
265+
self.tcx.dcx().emit_err(errors::UnstableAttrForAlreadyStableFeature {
266+
span: const_span.unwrap(), // If const_stab contains Some(..), same is true for const_span
267+
item_sp,
268+
});
269+
}
270+
}
255271
if let Some(ConstStability {
256272
level: Unstable { implied_by: Some(implied_by), .. },
257273
feature,

compiler/rustc_session/src/parse.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl GatedSpans {
6666
#[derive(Default)]
6767
pub struct SymbolGallery {
6868
/// All symbols occurred and their first occurrence span.
69-
pub symbols: Lock<FxHashMap<Symbol, Span>>,
69+
pub symbols: Lock<FxIndexMap<Symbol, Span>>,
7070
}
7171

7272
impl SymbolGallery {

library/std/src/rt.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,24 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
102102
sys::init(argc, argv, sigpipe)
103103
};
104104

105-
// Set up the current thread to give it the right name.
106-
let thread = Thread::new_main();
107-
thread::set_current(thread);
105+
// Set up the current thread handle to give it the right name.
106+
//
107+
// When code running before main uses `ReentrantLock` (for example by
108+
// using `println!`), the thread ID can become initialized before we
109+
// create this handle. Since `set_current` fails when the ID of the
110+
// handle does not match the current ID, we should attempt to use the
111+
// current thread ID here instead of unconditionally creating a new
112+
// one. Also see #130210.
113+
let thread = Thread::new_main(thread::current_id());
114+
if let Err(_thread) = thread::set_current(thread) {
115+
// `thread::current` will create a new handle if none has been set yet.
116+
// Thus, if someone uses it before main, this call will fail. That's a
117+
// bad idea though, as we then cannot set the main thread name here.
118+
//
119+
// FIXME: detect the main thread in `thread::current` and use the
120+
// correct name there.
121+
rtabort!("code running before main must not use thread::current");
122+
}
108123
}
109124

110125
/// Clean up the thread-local runtime state. This *should* be run after all other

library/std/src/thread/current.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,24 @@ mod id {
110110
}
111111
}
112112

113-
/// Sets the thread handle for the current thread.
114-
///
115-
/// Aborts if the handle or the ID has been set already.
116-
pub(crate) fn set_current(thread: Thread) {
117-
if CURRENT.get() != NONE || id::get().is_some() {
118-
// Using `panic` here can add ~3kB to the binary size. We have complete
119-
// control over where this is called, so just abort if there is a bug.
120-
rtabort!("thread::set_current should only be called once per thread");
113+
/// Tries to set the thread handle for the current thread. Fails if a handle was
114+
/// already set or if the thread ID of `thread` would change an already-set ID.
115+
pub(crate) fn set_current(thread: Thread) -> Result<(), Thread> {
116+
if CURRENT.get() != NONE {
117+
return Err(thread);
121118
}
122119

123-
id::set(thread.id());
120+
match id::get() {
121+
Some(id) if id == thread.id() => {}
122+
None => id::set(thread.id()),
123+
_ => return Err(thread),
124+
}
124125

125126
// Make sure that `crate::rt::thread_cleanup` will be run, which will
126127
// call `drop_current`.
127128
crate::sys::thread_local::guard::enable();
128129
CURRENT.set(thread.into_raw().cast_mut());
130+
Ok(())
129131
}
130132

131133
/// Gets the id of the thread that invokes it.

0 commit comments

Comments
 (0)