Skip to content

Rollup of 6 pull requests #115940

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Sep 18, 2023
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
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
- name: disable git crlf conversion
run: git config --global core.autocrlf false
- name: checkout the source code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: configure the PR in which the error message will be posted
Expand Down Expand Up @@ -435,7 +435,7 @@ jobs:
- name: disable git crlf conversion
run: git config --global core.autocrlf false
- name: checkout the source code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: configure the PR in which the error message will be posted
Expand Down Expand Up @@ -555,7 +555,7 @@ jobs:
- name: disable git crlf conversion
run: git config --global core.autocrlf false
- name: checkout the source code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: configure the PR in which the error message will be posted
Expand Down Expand Up @@ -662,7 +662,7 @@ jobs:
if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'"
steps:
- name: checkout the source code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: publish toolstate
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout the source code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: recursive
- name: install the bootstrap toolchain
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
pull-requests: write
steps:
- name: checkout the source code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: download Cargo.lock from update job
uses: actions/download-artifact@v3
Expand Down
17 changes: 14 additions & 3 deletions compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ pub fn expand_deriving_eq(
is_const: bool,
) {
let span = cx.with_def_site_ctxt(span);

let structural_trait_def = TraitDef {
span,
path: path_std!(marker::StructuralEq),
skip_path_as_bound: true, // crucial!
needs_copy_as_bound_if_packed: false,
additional_bounds: Vec::new(),
supports_unions: true,
methods: Vec::new(),
associated_types: Vec::new(),
is_const: false,
};
structural_trait_def.expand(cx, mitem, item, push);

let trait_def = TraitDef {
span,
path: path_std!(cmp::Eq),
Expand All @@ -44,9 +58,6 @@ pub fn expand_deriving_eq(
associated_types: Vec::new(),
is_const,
};

super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push);

trait_def.expand_ext(cx, mitem, item, push, true)
}

Expand Down
19 changes: 13 additions & 6 deletions compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,20 @@ pub fn expand_deriving_partial_eq(
BlockOrExpr::new_expr(expr)
}

super::inject_impl_of_structural_trait(
cx,
let structural_trait_def = TraitDef {
span,
item,
path_std!(marker::StructuralPartialEq),
push,
);
path: path_std!(marker::StructuralPartialEq),
skip_path_as_bound: true, // crucial!
needs_copy_as_bound_if_packed: false,
additional_bounds: Vec::new(),
// We really don't support unions, but that's already checked by the impl generated below;
// a second check here would lead to redundant error messages.
supports_unions: true,
methods: Vec::new(),
associated_types: Vec::new(),
is_const: false,
};
structural_trait_def.expand(cx, mitem, item, push);

// No need to generate `ne`, the default suffices, and not generating it is
// faster.
Expand Down
22 changes: 13 additions & 9 deletions compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,9 @@ impl<'a> TraitDef<'a> {
.collect();

// Require the current trait.
bounds.push(cx.trait_bound(trait_path.clone(), self.is_const));
if !self.skip_path_as_bound {
bounds.push(cx.trait_bound(trait_path.clone(), self.is_const));
}

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

let predicate = ast::WhereBoundPredicate {
span: self.span,
bound_generic_params: field_ty_param.bound_generic_params,
bounded_ty: field_ty_param.ty,
bounds,
};
if !bounds.is_empty() {
let predicate = ast::WhereBoundPredicate {
span: self.span,
bound_generic_params: field_ty_param.bound_generic_params,
bounded_ty: field_ty_param.ty,
bounds,
};

let predicate = ast::WherePredicate::BoundPredicate(predicate);
where_clause.predicates.push(predicate);
let predicate = ast::WherePredicate::BoundPredicate(predicate);
where_clause.predicates.push(predicate);
}
}
}
}
Expand Down
98 changes: 2 additions & 96 deletions compiler/rustc_builtin_macros/src/deriving/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::{GenericArg, Impl, ItemKind, MetaItem};
use rustc_ast::{GenericArg, MetaItem};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};

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

// Injects `impl<...> Structural for ItemType<...> { }`. In particular,
// does *not* add `where T: Structural` for parameters `T` in `...`.
// (That's the main reason we cannot use TraitDef here.)
fn inject_impl_of_structural_trait(
cx: &mut ExtCtxt<'_>,
span: Span,
item: &Annotatable,
structural_path: generic::ty::Path,
push: &mut dyn FnMut(Annotatable),
) {
let Annotatable::Item(item) = item else {
unreachable!();
};

let generics = match &item.kind {
ItemKind::Struct(_, generics) | ItemKind::Enum(_, generics) => generics,
// Do not inject `impl Structural for Union`. (`PartialEq` does not
// support unions, so we will see error downstream.)
ItemKind::Union(..) => return,
_ => unreachable!(),
};

// Create generics param list for where clauses and impl headers
let mut generics = generics.clone();

let ctxt = span.ctxt();

// Create the type of `self`.
//
// in addition, remove defaults from generic params (impls cannot have them).
let self_params: Vec<_> = generics
.params
.iter_mut()
.map(|param| match &mut param.kind {
ast::GenericParamKind::Lifetime => ast::GenericArg::Lifetime(
cx.lifetime(param.ident.span.with_ctxt(ctxt), param.ident),
),
ast::GenericParamKind::Type { default } => {
*default = None;
ast::GenericArg::Type(cx.ty_ident(param.ident.span.with_ctxt(ctxt), param.ident))
}
ast::GenericParamKind::Const { ty: _, kw_span: _, default } => {
*default = None;
ast::GenericArg::Const(
cx.const_ident(param.ident.span.with_ctxt(ctxt), param.ident),
)
}
})
.collect();

let type_ident = item.ident;

let trait_ref = cx.trait_ref(structural_path.to_path(cx, span, type_ident, &generics));
let self_type = cx.ty_path(cx.path_all(span, false, vec![type_ident], self_params));

// It would be nice to also encode constraint `where Self: Eq` (by adding it
// onto `generics` cloned above). Unfortunately, that strategy runs afoul of
// rust-lang/rust#48214. So we perform that additional check in the compiler
// itself, instead of encoding it here.

// Keep the lint and stability attributes of the original item, to control
// how the generated implementation is linted.
let mut attrs = ast::AttrVec::new();
attrs.extend(
item.attrs
.iter()
.filter(|a| {
[sym::allow, sym::warn, sym::deny, sym::forbid, sym::stable, sym::unstable]
.contains(&a.name_or_empty())
})
.cloned(),
);
// Mark as `automatically_derived` to avoid some silly lints.
attrs.push(cx.attr_word(sym::automatically_derived, span));

let newitem = cx.item(
span,
Ident::empty(),
attrs,
ItemKind::Impl(Box::new(Impl {
unsafety: ast::Unsafe::No,
polarity: ast::ImplPolarity::Positive,
defaultness: ast::Defaultness::Final,
constness: ast::Const::No,
generics,
of_trait: Some(trait_ref),
self_ty: self_type,
items: ThinVec::new(),
})),
);

push(Annotatable::Item(newitem));
}

fn assert_ty_bounds(
cx: &mut ExtCtxt<'_>,
stmts: &mut ThinVec<ast::Stmt>,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ fn layout_of<'tcx>(
let (param_env, ty) = query.into_parts();
debug!(?ty);

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

Expand Down
1 change: 0 additions & 1 deletion library/core/primitive_docs/box_into_raw.md

This file was deleted.

1 change: 0 additions & 1 deletion library/core/primitive_docs/fs_file.md

This file was deleted.

1 change: 0 additions & 1 deletion library/core/primitive_docs/io_bufread.md

This file was deleted.

1 change: 0 additions & 1 deletion library/core/primitive_docs/io_read.md

This file was deleted.

1 change: 0 additions & 1 deletion library/core/primitive_docs/io_seek.md

This file was deleted.

1 change: 0 additions & 1 deletion library/core/primitive_docs/io_write.md

This file was deleted.

1 change: 0 additions & 1 deletion library/core/primitive_docs/net_tosocketaddrs.md

This file was deleted.

1 change: 0 additions & 1 deletion library/core/primitive_docs/process_exit.md

This file was deleted.

1 change: 0 additions & 1 deletion library/core/primitive_docs/string_string.md

This file was deleted.

85 changes: 85 additions & 0 deletions library/core/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,91 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
}

/// Compares and sorts two values, returning minimum and maximum.
///
/// Returns `[v1, v2]` if the comparison determines them to be equal.
///
/// # Examples
///
/// ```
/// #![feature(cmp_minmax)]
/// use std::cmp;
///
/// assert_eq!(cmp::minmax(1, 2), [1, 2]);
/// assert_eq!(cmp::minmax(2, 2), [2, 2]);
///
/// // You can destructure the result using array patterns
/// let [min, max] = cmp::minmax(42, 17);
/// assert_eq!(min, 17);
/// assert_eq!(max, 42);
/// ```
#[inline]
#[must_use]
#[unstable(feature = "cmp_minmax", issue = "115939")]
pub fn minmax<T>(v1: T, v2: T) -> [T; 2]
where
T: Ord,
{
if v1 <= v2 { [v1, v2] } else { [v2, v1] }
}

/// Returns minimum and maximum values with respect to the specified comparison function.
///
/// Returns `[v1, v2]` if the comparison determines them to be equal.
///
/// # Examples
///
/// ```
/// #![feature(cmp_minmax)]
/// use std::cmp;
///
/// assert_eq!(cmp::minmax_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [1, -2]);
/// assert_eq!(cmp::minmax_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [-2, 2]);
///
/// // You can destructure the result using array patterns
/// let [min, max] = cmp::minmax_by(-42, 17, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
/// assert_eq!(min, 17);
/// assert_eq!(max, -42);
/// ```
#[inline]
#[must_use]
#[unstable(feature = "cmp_minmax", issue = "115939")]
pub fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
where
F: FnOnce(&T, &T) -> Ordering,
{
if compare(&v1, &v2).is_le() { [v1, v2] } else { [v2, v1] }
}

/// Returns minimum and maximum values with respect to the specified key function.
///
/// Returns `[v1, v2]` if the comparison determines them to be equal.
///
/// # Examples
///
/// ```
/// #![feature(cmp_minmax)]
/// use std::cmp;
///
/// assert_eq!(cmp::minmax_by_key(-2, 1, |x: &i32| x.abs()), [1, -2]);
/// assert_eq!(cmp::minmax_by_key(-2, 2, |x: &i32| x.abs()), [-2, 2]);
///
/// // You can destructure the result using array patterns
/// let [min, max] = cmp::minmax_by_key(-42, 17, |x: &i32| x.abs());
/// assert_eq!(min, 17);
/// assert_eq!(max, -42);
/// ```
#[inline]
#[must_use]
#[unstable(feature = "cmp_minmax", issue = "115939")]
pub fn minmax_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> [T; 2]
where
F: FnMut(&T) -> K,
K: Ord,
{
minmax_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
}

// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
mod impls {
use crate::cmp::Ordering::{self, Equal, Greater, Less};
Expand Down
Loading