Skip to content

Commit 4d69266

Browse files
committed
Auto merge of #115940 - matthiaskrgr:rollup-5ps9ln1, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #109409 (Add `minmax{,_by,_by_key}` functions to `core::cmp`) - #115494 (get rid of duplicate primitive_docs) - #115663 (ci: actions/checkout@v3 to actions/checkout@v4) - #115762 (Explain revealing of opaque types in layout_of ParamEnv) - #115891 (simplify inject_impl_of_structural_trait) - #115932 (Expand infra-ci reviewer list) r? `@ghost` `@rustbot` modify labels: rollup
2 parents b1575cb + 966f240 commit 4d69266

35 files changed

+151
-1767
lines changed

.github/workflows/ci.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
- name: disable git crlf conversion
6868
run: git config --global core.autocrlf false
6969
- name: checkout the source code
70-
uses: actions/checkout@v3
70+
uses: actions/checkout@v4
7171
with:
7272
fetch-depth: 2
7373
- name: configure the PR in which the error message will be posted
@@ -435,7 +435,7 @@ jobs:
435435
- name: disable git crlf conversion
436436
run: git config --global core.autocrlf false
437437
- name: checkout the source code
438-
uses: actions/checkout@v3
438+
uses: actions/checkout@v4
439439
with:
440440
fetch-depth: 2
441441
- name: configure the PR in which the error message will be posted
@@ -555,7 +555,7 @@ jobs:
555555
- name: disable git crlf conversion
556556
run: git config --global core.autocrlf false
557557
- name: checkout the source code
558-
uses: actions/checkout@v3
558+
uses: actions/checkout@v4
559559
with:
560560
fetch-depth: 2
561561
- name: configure the PR in which the error message will be posted
@@ -662,7 +662,7 @@ jobs:
662662
if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'"
663663
steps:
664664
- name: checkout the source code
665-
uses: actions/checkout@v3
665+
uses: actions/checkout@v4
666666
with:
667667
fetch-depth: 2
668668
- name: publish toolstate

.github/workflows/dependencies.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
runs-on: ubuntu-latest
5151
steps:
5252
- name: checkout the source code
53-
uses: actions/checkout@v3
53+
uses: actions/checkout@v4
5454
with:
5555
submodules: recursive
5656
- name: install the bootstrap toolchain
@@ -87,7 +87,7 @@ jobs:
8787
pull-requests: write
8888
steps:
8989
- name: checkout the source code
90-
uses: actions/checkout@v3
90+
uses: actions/checkout@v4
9191

9292
- name: download Cargo.lock from update job
9393
uses: actions/download-artifact@v3

compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ pub fn expand_deriving_eq(
1818
is_const: bool,
1919
) {
2020
let span = cx.with_def_site_ctxt(span);
21+
22+
let structural_trait_def = TraitDef {
23+
span,
24+
path: path_std!(marker::StructuralEq),
25+
skip_path_as_bound: true, // crucial!
26+
needs_copy_as_bound_if_packed: false,
27+
additional_bounds: Vec::new(),
28+
supports_unions: true,
29+
methods: Vec::new(),
30+
associated_types: Vec::new(),
31+
is_const: false,
32+
};
33+
structural_trait_def.expand(cx, mitem, item, push);
34+
2135
let trait_def = TraitDef {
2236
span,
2337
path: path_std!(cmp::Eq),
@@ -44,9 +58,6 @@ pub fn expand_deriving_eq(
4458
associated_types: Vec::new(),
4559
is_const,
4660
};
47-
48-
super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push);
49-
5061
trait_def.expand_ext(cx, mitem, item, push, true)
5162
}
5263

compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,20 @@ pub fn expand_deriving_partial_eq(
7272
BlockOrExpr::new_expr(expr)
7373
}
7474

75-
super::inject_impl_of_structural_trait(
76-
cx,
75+
let structural_trait_def = TraitDef {
7776
span,
78-
item,
79-
path_std!(marker::StructuralPartialEq),
80-
push,
81-
);
77+
path: path_std!(marker::StructuralPartialEq),
78+
skip_path_as_bound: true, // crucial!
79+
needs_copy_as_bound_if_packed: false,
80+
additional_bounds: Vec::new(),
81+
// We really don't support unions, but that's already checked by the impl generated below;
82+
// a second check here would lead to redundant error messages.
83+
supports_unions: true,
84+
methods: Vec::new(),
85+
associated_types: Vec::new(),
86+
is_const: false,
87+
};
88+
structural_trait_def.expand(cx, mitem, item, push);
8289

8390
// No need to generate `ne`, the default suffices, and not generating it is
8491
// faster.

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,9 @@ impl<'a> TraitDef<'a> {
711711
.collect();
712712

713713
// Require the current trait.
714-
bounds.push(cx.trait_bound(trait_path.clone(), self.is_const));
714+
if !self.skip_path_as_bound {
715+
bounds.push(cx.trait_bound(trait_path.clone(), self.is_const));
716+
}
715717

716718
// Add a `Copy` bound if required.
717719
if is_packed && self.needs_copy_as_bound_if_packed {
@@ -722,15 +724,17 @@ impl<'a> TraitDef<'a> {
722724
));
723725
}
724726

725-
let predicate = ast::WhereBoundPredicate {
726-
span: self.span,
727-
bound_generic_params: field_ty_param.bound_generic_params,
728-
bounded_ty: field_ty_param.ty,
729-
bounds,
730-
};
727+
if !bounds.is_empty() {
728+
let predicate = ast::WhereBoundPredicate {
729+
span: self.span,
730+
bound_generic_params: field_ty_param.bound_generic_params,
731+
bounded_ty: field_ty_param.ty,
732+
bounds,
733+
};
731734

732-
let predicate = ast::WherePredicate::BoundPredicate(predicate);
733-
where_clause.predicates.push(predicate);
735+
let predicate = ast::WherePredicate::BoundPredicate(predicate);
736+
where_clause.predicates.push(predicate);
737+
}
734738
}
735739
}
736740
}

compiler/rustc_builtin_macros/src/deriving/mod.rs

+2-96
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
33
use rustc_ast as ast;
44
use rustc_ast::ptr::P;
5-
use rustc_ast::{GenericArg, Impl, ItemKind, MetaItem};
5+
use rustc_ast::{GenericArg, MetaItem};
66
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
7-
use rustc_span::symbol::{sym, Ident, Symbol};
7+
use rustc_span::symbol::{sym, Symbol};
88
use rustc_span::Span;
99
use thin_vec::{thin_vec, ThinVec};
1010

@@ -116,100 +116,6 @@ fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> {
116116
}))
117117
}
118118

119-
// Injects `impl<...> Structural for ItemType<...> { }`. In particular,
120-
// does *not* add `where T: Structural` for parameters `T` in `...`.
121-
// (That's the main reason we cannot use TraitDef here.)
122-
fn inject_impl_of_structural_trait(
123-
cx: &mut ExtCtxt<'_>,
124-
span: Span,
125-
item: &Annotatable,
126-
structural_path: generic::ty::Path,
127-
push: &mut dyn FnMut(Annotatable),
128-
) {
129-
let Annotatable::Item(item) = item else {
130-
unreachable!();
131-
};
132-
133-
let generics = match &item.kind {
134-
ItemKind::Struct(_, generics) | ItemKind::Enum(_, generics) => generics,
135-
// Do not inject `impl Structural for Union`. (`PartialEq` does not
136-
// support unions, so we will see error downstream.)
137-
ItemKind::Union(..) => return,
138-
_ => unreachable!(),
139-
};
140-
141-
// Create generics param list for where clauses and impl headers
142-
let mut generics = generics.clone();
143-
144-
let ctxt = span.ctxt();
145-
146-
// Create the type of `self`.
147-
//
148-
// in addition, remove defaults from generic params (impls cannot have them).
149-
let self_params: Vec<_> = generics
150-
.params
151-
.iter_mut()
152-
.map(|param| match &mut param.kind {
153-
ast::GenericParamKind::Lifetime => ast::GenericArg::Lifetime(
154-
cx.lifetime(param.ident.span.with_ctxt(ctxt), param.ident),
155-
),
156-
ast::GenericParamKind::Type { default } => {
157-
*default = None;
158-
ast::GenericArg::Type(cx.ty_ident(param.ident.span.with_ctxt(ctxt), param.ident))
159-
}
160-
ast::GenericParamKind::Const { ty: _, kw_span: _, default } => {
161-
*default = None;
162-
ast::GenericArg::Const(
163-
cx.const_ident(param.ident.span.with_ctxt(ctxt), param.ident),
164-
)
165-
}
166-
})
167-
.collect();
168-
169-
let type_ident = item.ident;
170-
171-
let trait_ref = cx.trait_ref(structural_path.to_path(cx, span, type_ident, &generics));
172-
let self_type = cx.ty_path(cx.path_all(span, false, vec![type_ident], self_params));
173-
174-
// It would be nice to also encode constraint `where Self: Eq` (by adding it
175-
// onto `generics` cloned above). Unfortunately, that strategy runs afoul of
176-
// rust-lang/rust#48214. So we perform that additional check in the compiler
177-
// itself, instead of encoding it here.
178-
179-
// Keep the lint and stability attributes of the original item, to control
180-
// how the generated implementation is linted.
181-
let mut attrs = ast::AttrVec::new();
182-
attrs.extend(
183-
item.attrs
184-
.iter()
185-
.filter(|a| {
186-
[sym::allow, sym::warn, sym::deny, sym::forbid, sym::stable, sym::unstable]
187-
.contains(&a.name_or_empty())
188-
})
189-
.cloned(),
190-
);
191-
// Mark as `automatically_derived` to avoid some silly lints.
192-
attrs.push(cx.attr_word(sym::automatically_derived, span));
193-
194-
let newitem = cx.item(
195-
span,
196-
Ident::empty(),
197-
attrs,
198-
ItemKind::Impl(Box::new(Impl {
199-
unsafety: ast::Unsafe::No,
200-
polarity: ast::ImplPolarity::Positive,
201-
defaultness: ast::Defaultness::Final,
202-
constness: ast::Const::No,
203-
generics,
204-
of_trait: Some(trait_ref),
205-
self_ty: self_type,
206-
items: ThinVec::new(),
207-
})),
208-
);
209-
210-
push(Annotatable::Item(newitem));
211-
}
212-
213119
fn assert_ty_bounds(
214120
cx: &mut ExtCtxt<'_>,
215121
stmts: &mut ThinVec<ast::Stmt>,

compiler/rustc_ty_utils/src/layout.rs

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ fn layout_of<'tcx>(
3636
let (param_env, ty) = query.into_parts();
3737
debug!(?ty);
3838

39+
// Optimization: We convert to RevealAll and convert opaque types in the where bounds
40+
// to their hidden types. This reduces overall uncached invocations of `layout_of` and
41+
// is thus a small performance improvement.
3942
let param_env = param_env.with_reveal_all_normalized(tcx);
4043
let unnormalized_ty = ty;
4144

library/core/primitive_docs/box_into_raw.md

-1
This file was deleted.

library/core/primitive_docs/fs_file.md

-1
This file was deleted.

library/core/primitive_docs/io_bufread.md

-1
This file was deleted.

library/core/primitive_docs/io_read.md

-1
This file was deleted.

library/core/primitive_docs/io_seek.md

-1
This file was deleted.

library/core/primitive_docs/io_write.md

-1
This file was deleted.

library/core/primitive_docs/net_tosocketaddrs.md

-1
This file was deleted.

library/core/primitive_docs/process_exit.md

-1
This file was deleted.

library/core/primitive_docs/string_string.md

-1
This file was deleted.

library/core/src/cmp.rs

+85
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,91 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
12891289
max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
12901290
}
12911291

1292+
/// Compares and sorts two values, returning minimum and maximum.
1293+
///
1294+
/// Returns `[v1, v2]` if the comparison determines them to be equal.
1295+
///
1296+
/// # Examples
1297+
///
1298+
/// ```
1299+
/// #![feature(cmp_minmax)]
1300+
/// use std::cmp;
1301+
///
1302+
/// assert_eq!(cmp::minmax(1, 2), [1, 2]);
1303+
/// assert_eq!(cmp::minmax(2, 2), [2, 2]);
1304+
///
1305+
/// // You can destructure the result using array patterns
1306+
/// let [min, max] = cmp::minmax(42, 17);
1307+
/// assert_eq!(min, 17);
1308+
/// assert_eq!(max, 42);
1309+
/// ```
1310+
#[inline]
1311+
#[must_use]
1312+
#[unstable(feature = "cmp_minmax", issue = "115939")]
1313+
pub fn minmax<T>(v1: T, v2: T) -> [T; 2]
1314+
where
1315+
T: Ord,
1316+
{
1317+
if v1 <= v2 { [v1, v2] } else { [v2, v1] }
1318+
}
1319+
1320+
/// Returns minimum and maximum values with respect to the specified comparison function.
1321+
///
1322+
/// Returns `[v1, v2]` if the comparison determines them to be equal.
1323+
///
1324+
/// # Examples
1325+
///
1326+
/// ```
1327+
/// #![feature(cmp_minmax)]
1328+
/// use std::cmp;
1329+
///
1330+
/// assert_eq!(cmp::minmax_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [1, -2]);
1331+
/// assert_eq!(cmp::minmax_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [-2, 2]);
1332+
///
1333+
/// // You can destructure the result using array patterns
1334+
/// let [min, max] = cmp::minmax_by(-42, 17, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
1335+
/// assert_eq!(min, 17);
1336+
/// assert_eq!(max, -42);
1337+
/// ```
1338+
#[inline]
1339+
#[must_use]
1340+
#[unstable(feature = "cmp_minmax", issue = "115939")]
1341+
pub fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
1342+
where
1343+
F: FnOnce(&T, &T) -> Ordering,
1344+
{
1345+
if compare(&v1, &v2).is_le() { [v1, v2] } else { [v2, v1] }
1346+
}
1347+
1348+
/// Returns minimum and maximum values with respect to the specified key function.
1349+
///
1350+
/// Returns `[v1, v2]` if the comparison determines them to be equal.
1351+
///
1352+
/// # Examples
1353+
///
1354+
/// ```
1355+
/// #![feature(cmp_minmax)]
1356+
/// use std::cmp;
1357+
///
1358+
/// assert_eq!(cmp::minmax_by_key(-2, 1, |x: &i32| x.abs()), [1, -2]);
1359+
/// assert_eq!(cmp::minmax_by_key(-2, 2, |x: &i32| x.abs()), [-2, 2]);
1360+
///
1361+
/// // You can destructure the result using array patterns
1362+
/// let [min, max] = cmp::minmax_by_key(-42, 17, |x: &i32| x.abs());
1363+
/// assert_eq!(min, 17);
1364+
/// assert_eq!(max, -42);
1365+
/// ```
1366+
#[inline]
1367+
#[must_use]
1368+
#[unstable(feature = "cmp_minmax", issue = "115939")]
1369+
pub fn minmax_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> [T; 2]
1370+
where
1371+
F: FnMut(&T) -> K,
1372+
K: Ord,
1373+
{
1374+
minmax_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
1375+
}
1376+
12921377
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
12931378
mod impls {
12941379
use crate::cmp::Ordering::{self, Equal, Greater, Less};

0 commit comments

Comments
 (0)