Skip to content

Commit a774033

Browse files
committed
Auto merge of #158426 - jhpratt:rollup-SeRw4IY, r=jhpratt
Rollup of 3 pull requests Successful merges: - #152225 (Add supertrait item shadowing for type-level path resolution) - #158244 (Attribute docs `deprecated` , `warn`, `allow`, `cfg`, `deny`, and `forbid` ) - #158399 (std: truncate thread names on NetBSD)
2 parents 40557f6 + d865b43 commit a774033

47 files changed

Lines changed: 1502 additions & 455 deletions

Some content is hidden

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

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,9 +409,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
409409

410410
pub(super) fn report_ambiguous_assoc_item(
411411
&self,
412-
bound1: ty::PolyTraitRef<'tcx>,
413-
bound2: ty::PolyTraitRef<'tcx>,
414-
matching_candidates: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
412+
matching_candidates: &[ty::PolyTraitRef<'tcx>],
415413
qself: AssocItemQSelf,
416414
assoc_tag: ty::AssocTag,
417415
assoc_ident: Ident,
@@ -443,7 +441,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
443441
// predicates!).
444442
// FIXME: Turn this into a structured, translatable & more actionable suggestion.
445443
let mut where_bounds = vec![];
446-
for bound in [bound1, bound2].into_iter().chain(matching_candidates) {
444+
for &bound in matching_candidates {
447445
let bound_id = bound.def_id();
448446
let assoc_item = tcx.associated_items(bound_id).find_by_ident_and_kind(
449447
tcx,

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use std::{assert_matches, slice};
2424
use rustc_abi::FIRST_VARIANT;
2525
use rustc_ast::LitKind;
2626
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
27+
use rustc_data_structures::sso::SsoHashSet;
2728
use rustc_errors::codes::*;
2829
use rustc_errors::{
2930
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, StashKey,
@@ -1262,6 +1263,74 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12621263
)
12631264
}
12641265

1266+
/// When there are multiple traits which contain an identically named
1267+
/// associated item, this function eliminates any traits which are a
1268+
/// supertrait of another candidate trait.
1269+
///
1270+
/// This is the type-level analogue of
1271+
/// `rustc_hir_typeck::method::probe::ProbeContext::collapse_candidates_to_subtrait_pick`;
1272+
/// keep both implementations in sync.
1273+
///
1274+
/// This implements RFC #3624.
1275+
fn collapse_candidates_to_subtrait_pick(
1276+
&self,
1277+
matching_candidates: &[ty::PolyTraitRef<'tcx>],
1278+
) -> Option<ty::PolyTraitRef<'tcx>> {
1279+
if !self.tcx().features().supertrait_item_shadowing() {
1280+
return None;
1281+
}
1282+
1283+
let mut child_trait = matching_candidates[0];
1284+
let mut supertraits: SsoHashSet<_> =
1285+
traits::supertrait_def_ids(self.tcx(), child_trait.def_id()).collect();
1286+
1287+
let mut remaining_candidates: Vec<_> = matching_candidates[1..].iter().copied().collect();
1288+
while !remaining_candidates.is_empty() {
1289+
let mut made_progress = false;
1290+
let mut next_round = vec![];
1291+
1292+
for remaining_trait in remaining_candidates {
1293+
if supertraits.contains(&remaining_trait.def_id()) {
1294+
made_progress = true;
1295+
continue;
1296+
}
1297+
1298+
// This candidate is not a supertrait of the `child_trait`.
1299+
// Check if it's a subtrait of the `child_trait`, instead.
1300+
// If it is, then it must have been a subtrait of every
1301+
// other pick we've eliminated at this point. It will
1302+
// take over at this point.
1303+
let remaining_trait_supertraits: SsoHashSet<_> =
1304+
traits::supertrait_def_ids(self.tcx(), remaining_trait.def_id()).collect();
1305+
if remaining_trait_supertraits.contains(&child_trait.def_id()) {
1306+
child_trait = remaining_trait;
1307+
supertraits = remaining_trait_supertraits;
1308+
made_progress = true;
1309+
continue;
1310+
}
1311+
1312+
// Neither `child_trait` or the current candidate are
1313+
// supertraits of each other.
1314+
// Don't bail here, since we may be comparing two supertraits
1315+
// of a common subtrait. These two supertraits won't be related
1316+
// at all, but we will pick them up next round when we find their
1317+
// child as we continue iterating in this round.
1318+
next_round.push(remaining_trait);
1319+
}
1320+
1321+
if made_progress {
1322+
// If we've made progress, iterate again.
1323+
remaining_candidates = next_round;
1324+
} else {
1325+
// Otherwise, we must have at least two candidates which
1326+
// are not related to each other at all.
1327+
return None;
1328+
}
1329+
}
1330+
1331+
Some(child_trait)
1332+
}
1333+
12651334
/// Search for a single trait bound whose trait defines the associated item given by
12661335
/// `assoc_ident`.
12671336
///
@@ -1296,10 +1365,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12961365
};
12971366

12981367
if let Some(bound2) = matching_candidates.next() {
1368+
let all_matching_candidates: Vec<_> =
1369+
[bound1, bound2].into_iter().chain(matching_candidates).collect();
1370+
if let Some(bound) = self.collapse_candidates_to_subtrait_pick(&all_matching_candidates)
1371+
{
1372+
return Ok(bound);
1373+
}
1374+
12991375
return Err(self.report_ambiguous_assoc_item(
1300-
bound1,
1301-
bound2,
1302-
matching_candidates,
1376+
&all_matching_candidates,
13031377
qself,
13041378
assoc_tag,
13051379
assoc_ident,

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2359,6 +2359,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
23592359
/// multiple conflicting picks if there is one pick whose trait container is a subtrait
23602360
/// of the trait containers of all of the other picks.
23612361
///
2362+
/// This is the method-probe analogue of
2363+
/// `rustc_hir_analysis::hir_ty_lowering::HirTyLowerer::collapse_candidates_to_subtrait_pick`;
2364+
/// keep both implementations in sync.
2365+
///
23622366
/// This implements RFC #3624.
23632367
fn collapse_candidates_to_subtrait_pick(
23642368
&self,

library/std/src/attribute_docs.rs

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,253 @@
8585
/// [`unused_must_use`]: ../rustc/lints/listing/warn-by-default.html#unused-must-use
8686
/// [the `must_use` attribute]: ../reference/attributes/diagnostics.html#the-must_use-attribute
8787
mod must_use_attribute {}
88+
89+
#[doc(attribute = "allow")]
90+
//
91+
/// The `allow` attribute suppresses lint diagnostics that would otherwise produce
92+
/// warnings or errors. It can be used on any lint or lint group (except those
93+
/// set to `forbid`).
94+
///
95+
/// ```rust
96+
/// #[allow(dead_code)]
97+
/// fn unused_function() {
98+
/// // ...
99+
/// }
100+
///
101+
/// fn main() {
102+
/// // `unused_function` does not generate a compiler warning.
103+
/// }
104+
/// ```
105+
///
106+
/// Without `#[allow(dead_code)]`, the example above would emit:
107+
///
108+
/// ```text
109+
/// warning: function `unused_function` is never used
110+
/// --> main.rs:1:4
111+
/// |
112+
/// 1 | fn unused_function() {
113+
/// | ^^^^^^^^^^^^^^^
114+
/// |
115+
/// = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
116+
///
117+
/// warning: 1 warning emitted
118+
/// ```
119+
///
120+
/// Multiple lints can be set to `allow` at once with commas:
121+
///
122+
/// ```rust
123+
/// #[allow(unused_variables, unused_mut)]
124+
/// fn main() {
125+
/// let mut x: u32 = 42;
126+
/// }
127+
/// ```
128+
///
129+
/// This is mostly used to prevent lint warnings or errors while still under development.
130+
///
131+
/// It cannot override a lint that has been set to `forbid`.
132+
///
133+
/// It's also important to consider that overusing `allow` could make code harder to maintain
134+
/// and possibly hide issues. To mitigate this issue, using the `expect` attribute is preferred.
135+
///
136+
/// `allow` can be overridden by `warn`, `deny`, and `forbid`.
137+
///
138+
/// The lint checks supported by rustc can be found via `rustc -W help`,
139+
/// along with their default settings and are documented in [the `rustc` book].
140+
///
141+
/// [the `rustc` book]: ../rustc/lints/listing/index.html
142+
///
143+
/// For more information, see the Reference on [the `allow` attribute].
144+
///
145+
/// [the `allow` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes
146+
mod allow_attribute {}
147+
148+
#[doc(attribute = "cfg")]
149+
//
150+
/// Used for conditional compilation.
151+
///
152+
/// The `cfg` attribute allows compiling an item under specific conditions, otherwise it
153+
/// will be ignored.
154+
///
155+
/// ```rust
156+
/// // Only compiles this function for Linux.
157+
/// #[cfg(target_os = "linux")]
158+
/// fn platform_specific() {
159+
/// println!("Running on Linux");
160+
/// }
161+
///
162+
/// // Only compiles this function if not for Linux.
163+
/// #[cfg(not(target_os = "linux"))]
164+
/// fn platform_specific() {
165+
/// println!("Running on something else");
166+
/// }
167+
/// ```
168+
///
169+
/// Depending on the platform you're targeting, only one of these two functions will be considered
170+
/// during the compilation.
171+
///
172+
/// Conditions can also be combined with `all(...)`, `any(...)`, and `not(...)`.
173+
///
174+
/// * `all`: True if all given predicates are true.
175+
/// * `any`: True if at least one of the given predicates is true.
176+
/// * `not`: True if the predicate is false and false if the predicate is true.
177+
///
178+
/// ```rust
179+
/// #[cfg(all(unix, target_pointer_width = "64"))]
180+
/// fn unix_64bit() {
181+
/// }
182+
/// ```
183+
///
184+
/// If you want to use this mechanism in an `if` condition in your code, you
185+
/// can use the [`cfg!`] macro. To conditionally apply an attribute,
186+
/// see [`cfg_attr`].
187+
///
188+
/// For more information, see the Reference on [the `cfg` attribute].
189+
///
190+
/// [`cfg_attr`]: ../reference/conditional-compilation.html#the-cfg_attr-attribute
191+
/// [the `cfg` attribute]: ../reference/conditional-compilation.html#the-cfg-attribute
192+
mod cfg_attribute {}
193+
194+
#[doc(attribute = "deny")]
195+
//
196+
/// Emits an error, preventing the compilation from finishing, when a lint check has failed.
197+
/// This is useful for enforcing rules or preventing certain patterns:
198+
///
199+
/// ```rust,compile_fail
200+
/// #[deny(unused)]
201+
/// fn foo() {
202+
/// let x = 42; // Emits an error because x is unused.
203+
/// }
204+
/// ```
205+
///
206+
/// `deny` can be overridden by `allow`, `warn`, and `forbid`:
207+
///
208+
/// ```rust
209+
/// #![deny(unused)]
210+
///
211+
/// #[allow(unused)] // We override the `deny` for this function.
212+
/// fn foo() {
213+
/// let x = 42; // No lint emitted even though `x` is unused.
214+
/// }
215+
/// ```
216+
///
217+
/// Multiple lints can also be set to `deny` at once:
218+
///
219+
/// ```rust,compile_fail
220+
/// #![deny(unused_imports, unused_variables)]
221+
/// use std::collections::*;
222+
///
223+
/// fn main() {
224+
/// let mut x = 10;
225+
/// }
226+
/// ```
227+
///
228+
/// The lint checks supported by rustc can be found via `rustc -W help`,
229+
/// along with their default settings and are documented in [the `rustc` book].
230+
///
231+
/// [the `rustc` book]: ../rustc/lints/listing/index.html
232+
///
233+
/// For more information, see the Reference on [the `deny` attribute].
234+
///
235+
/// [the `deny` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes
236+
mod deny_attribute {}
237+
238+
#[doc(attribute = "forbid")]
239+
//
240+
/// Emits an error, preventing the compilation from finishing, when a lint check has failed.
241+
///
242+
/// A lint set to `forbid` cannot be overridden by `allow` or `warn`.
243+
/// Attempting either will result in a compilation error. Writing `#[deny(...)]` on the same lint inside a
244+
/// `forbid` scope is permitted, but has no effect; the lint remains at the `forbid` level.
245+
///
246+
/// This is useful for enforcing strict policies that should not be relaxed
247+
/// anywhere in the codebase. Example:
248+
///
249+
/// ```rust
250+
/// #![forbid(unsafe_code)]
251+
///
252+
/// // This would cause a compilation error if uncommented:
253+
/// // #[allow(unsafe_code)] // error: cannot override `forbid`
254+
/// ```
255+
///
256+
/// Multiple lints can be set to `forbid` at once:
257+
///
258+
/// ```rust
259+
/// #![forbid(unsafe_code, unused)]
260+
/// ```
261+
///
262+
/// The lint checks supported by rustc can be found via `rustc -W help`,
263+
/// along with their default settings and are documented in [the `rustc` book].
264+
///
265+
/// [the `rustc` book]: ../rustc/lints/listing/index.html
266+
///
267+
/// For more information, see the Reference on [the `forbid` attribute].
268+
///
269+
/// [the `forbid` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes
270+
mod forbid_attribute {}
271+
272+
#[doc(attribute = "deprecated")]
273+
//
274+
/// Emits a warning during compilation when an item with this attribute is used.
275+
/// `since` and `note` are optional fields giving more detail about why the item is deprecated.
276+
///
277+
/// * `since`: the version since when the item is deprecated.
278+
/// * `note`: the reason why an item is deprecated.
279+
///
280+
/// Example:
281+
///
282+
/// ```rust
283+
/// #[deprecated(since = "1.0.0", note = "Use bar instead")]
284+
/// struct Foo;
285+
/// struct Bar;
286+
/// ```
287+
///
288+
/// `deprecated` attribute helps developers transition away from old code by providing warnings when
289+
/// deprecated items are used. Note that during `Cargo` builds, warnings on dependencies get silenced
290+
/// by default, so you may not see a deprecation warning unless you build that dependency directly.
291+
///
292+
/// For more information, see the Reference on [the `deprecated` attribute].
293+
///
294+
/// [the `deprecated` attribute]: ../reference/attributes/diagnostics.html#the-deprecated-attribute
295+
mod deprecated_attribute {}
296+
297+
#[doc(attribute = "warn")]
298+
//
299+
/// Emits a warning during compilation when a lint check failed.
300+
///
301+
/// Unlike `deny` or `forbid`, `warn` does not produce a hard error: the compilation continues, but
302+
/// the compiler emits a warning message. `warn` can be overridden by `allow`, `deny`, and `forbid`.
303+
///
304+
/// Example:
305+
///
306+
/// ```rust,compile_fail
307+
/// #![allow(unused)]
308+
///
309+
/// #[warn(unused)] // We override the allowed `unused` lint.
310+
/// fn foo() {
311+
/// // This lint warns by default even without #[warn(unused)] being explicitly set
312+
/// let x = 42; // warning: unused variable `x`
313+
/// }
314+
/// ```
315+
///
316+
///
317+
/// Many lints, including `unused`, are already set to `warn` by default so this attribute is
318+
/// mainly useful for lints that are normally `allow` by default.
319+
///
320+
/// Multiple lints can be set to `warn` at once:
321+
///
322+
/// ```rust,compile_fail
323+
/// #[warn(unused_mut, unused_variables)]
324+
/// fn main() {
325+
/// let mut x = 42;
326+
/// }
327+
/// ```
328+
///
329+
/// The lint checks supported by rustc can be found via `rustc -W help`,
330+
/// along with their default settings and are documented in [the `rustc` book].
331+
///
332+
/// [the `rustc` book]: ../rustc/lints/listing/index.html
333+
///
334+
/// For more information, see the Reference on [the `warn` attribute].
335+
///
336+
/// [the `warn` attribute]: ../reference/attributes/diagnostics.html#lint-check-attributes
337+
mod warn_attribute {}

0 commit comments

Comments
 (0)