mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Remove Ord
from ClosureKind
Using `Ord` to accomplish a meaning of subset relationship can be hard to read. The existing uses for that are easily replaced with a `match`, and in my opinion, more readable without needing to resorting to comments to explain the intention.
This commit is contained in:
parent
09bc67b915
commit
7e1969ac13
@ -19,7 +19,7 @@ use rustc_target::spec::abi::Abi;
|
|||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
use rustc_trait_selection::traits::error_reporting::ArgKind;
|
use rustc_trait_selection::traits::error_reporting::ArgKind;
|
||||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
|
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
|
||||||
use std::cmp;
|
use rustc_type_ir::ClosureKind;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
@ -437,10 +437,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(found_kind) = found_kind {
|
if let Some(found_kind) = found_kind {
|
||||||
expected_kind = Some(
|
// always use the closure kind that is more permissive.
|
||||||
expected_kind
|
match (expected_kind, found_kind) {
|
||||||
.map_or_else(|| found_kind, |current| cmp::min(current, found_kind)),
|
(None, _) => expected_kind = Some(found_kind),
|
||||||
);
|
(Some(ClosureKind::FnMut), ClosureKind::Fn) => {
|
||||||
|
expected_kind = Some(ClosureKind::Fn)
|
||||||
|
}
|
||||||
|
(Some(ClosureKind::FnOnce), ClosureKind::Fn | ClosureKind::FnMut) => {
|
||||||
|
expected_kind = Some(found_kind)
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ pub struct Instance<'tcx> {
|
|||||||
pub args: GenericArgsRef<'tcx>,
|
pub args: GenericArgsRef<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
|
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||||
pub enum InstanceDef<'tcx> {
|
pub enum InstanceDef<'tcx> {
|
||||||
/// A user-defined callable item.
|
/// A user-defined callable item.
|
||||||
|
@ -7,6 +7,7 @@ use rustc_middle::ty::GenericArgsRef;
|
|||||||
use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
|
use rustc_type_ir::ClosureKind;
|
||||||
use traits::{translate_args, Reveal};
|
use traits::{translate_args, Reveal};
|
||||||
|
|
||||||
use crate::errors::UnexpectedFnPtrAssociatedItem;
|
use crate::errors::UnexpectedFnPtrAssociatedItem;
|
||||||
@ -296,23 +297,25 @@ fn resolve_associated_item<'tcx>(
|
|||||||
{
|
{
|
||||||
match *rcvr_args.type_at(0).kind() {
|
match *rcvr_args.type_at(0).kind() {
|
||||||
ty::CoroutineClosure(coroutine_closure_def_id, args) => {
|
ty::CoroutineClosure(coroutine_closure_def_id, args) => {
|
||||||
// If we're computing `AsyncFnOnce`/`AsyncFnMut` for a by-ref closure,
|
match (target_kind, args.as_coroutine_closure().kind()) {
|
||||||
// or `AsyncFnOnce` for a by-mut closure, then construct a new body that
|
(ClosureKind::FnOnce | ClosureKind::FnMut, ClosureKind::Fn)
|
||||||
// has the right return types.
|
| (ClosureKind::FnOnce, ClosureKind::FnMut) => {
|
||||||
//
|
// If we're computing `AsyncFnOnce`/`AsyncFnMut` for a by-ref closure,
|
||||||
// Specifically, `AsyncFnMut` for a by-ref coroutine-closure just needs
|
// or `AsyncFnOnce` for a by-mut closure, then construct a new body that
|
||||||
// to have its input and output types fixed (`&mut self` and returning
|
// has the right return types.
|
||||||
// `i16` coroutine kind).
|
//
|
||||||
if target_kind > args.as_coroutine_closure().kind() {
|
// Specifically, `AsyncFnMut` for a by-ref coroutine-closure just needs
|
||||||
Some(Instance {
|
// to have its input and output types fixed (`&mut self` and returning
|
||||||
def: ty::InstanceDef::ConstructCoroutineInClosureShim {
|
// `i16` coroutine kind).
|
||||||
coroutine_closure_def_id,
|
Some(Instance {
|
||||||
target_kind,
|
def: ty::InstanceDef::ConstructCoroutineInClosureShim {
|
||||||
},
|
coroutine_closure_def_id,
|
||||||
args,
|
target_kind,
|
||||||
})
|
},
|
||||||
} else {
|
args,
|
||||||
Some(Instance::new(coroutine_closure_def_id, args))
|
})
|
||||||
|
}
|
||||||
|
_ => Some(Instance::new(coroutine_closure_def_id, args)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Closure(closure_def_id, args) => {
|
ty::Closure(closure_def_id, args) => {
|
||||||
|
@ -369,12 +369,9 @@ rustc_index::newtype_index! {
|
|||||||
///
|
///
|
||||||
/// You can get the environment type of a closure using
|
/// You can get the environment type of a closure using
|
||||||
/// `tcx.closure_env_ty()`.
|
/// `tcx.closure_env_ty()`.
|
||||||
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||||
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
|
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
|
||||||
pub enum ClosureKind {
|
pub enum ClosureKind {
|
||||||
// Warning: Ordering is significant here! The ordering is chosen
|
|
||||||
// because the trait Fn is a subtrait of FnMut and so in turn, and
|
|
||||||
// hence we order it so that Fn < FnMut < FnOnce.
|
|
||||||
Fn,
|
Fn,
|
||||||
FnMut,
|
FnMut,
|
||||||
FnOnce,
|
FnOnce,
|
||||||
@ -394,8 +391,15 @@ impl ClosureKind {
|
|||||||
|
|
||||||
/// Returns `true` if a type that impls this closure kind
|
/// Returns `true` if a type that impls this closure kind
|
||||||
/// must also implement `other`.
|
/// must also implement `other`.
|
||||||
|
#[rustfmt::skip]
|
||||||
pub fn extends(self, other: ClosureKind) -> bool {
|
pub fn extends(self, other: ClosureKind) -> bool {
|
||||||
self <= other
|
use ClosureKind::*;
|
||||||
|
match (self, other) {
|
||||||
|
(Fn, Fn | FnMut | FnOnce)
|
||||||
|
| (FnMut, FnMut | FnOnce)
|
||||||
|
| (FnOnce, FnOnce) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user