Rollup merge of #104890 - lcnr:small-cleanup, r=fee1-dead
small method code cleanup
This commit is contained in:
commit
8a84dd8fcc
6 changed files with 47 additions and 92 deletions
|
@ -179,12 +179,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
// Hack: we know that there are traits implementing Fn for &F
|
// Hack: we know that there are traits implementing Fn for &F
|
||||||
// where F:Fn and so forth. In the particular case of types
|
// where F:Fn and so forth. In the particular case of types
|
||||||
// like `x: &mut FnMut()`, if there is a call `x()`, we would
|
// like `f: &mut FnMut()`, if there is a call `f()`, we would
|
||||||
// normally translate to `FnMut::call_mut(&mut x, ())`, but
|
// normally translate to `FnMut::call_mut(&mut f, ())`, but
|
||||||
// that winds up requiring `mut x: &mut FnMut()`. A little
|
// that winds up potentially requiring the user to mark their
|
||||||
// over the top. The simplest fix by far is to just ignore
|
// variable as `mut` which feels unnecessary and unexpected.
|
||||||
// this case and deref again, so we wind up with
|
//
|
||||||
// `FnMut::call_mut(&mut *x, ())`.
|
// fn foo(f: &mut impl FnMut()) { f() }
|
||||||
|
// ^ without this hack `f` would have to be declared as mutable
|
||||||
|
//
|
||||||
|
// The simplest fix by far is to just ignore this case and deref again,
|
||||||
|
// so we wind up with `FnMut::call_mut(&mut *f, ())`.
|
||||||
ty::Ref(..) if autoderef.step_count() == 0 => {
|
ty::Ref(..) if autoderef.step_count() == 0 => {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ use rustc_span::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
|
|
||||||
|
|
||||||
/// Reifies a cast check to be checked once we have full type information for
|
/// Reifies a cast check to be checked once we have full type information for
|
||||||
/// a function context.
|
/// a function context.
|
||||||
|
@ -727,9 +726,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
debug!(" -> CoercionCast");
|
debug!(" -> CoercionCast");
|
||||||
fcx.typeck_results.borrow_mut().set_coercion_cast(self.expr.hir_id.local_id);
|
fcx.typeck_results.borrow_mut().set_coercion_cast(self.expr.hir_id.local_id);
|
||||||
}
|
}
|
||||||
Err(ty::error::TypeError::ObjectUnsafeCoercion(did)) => {
|
|
||||||
self.report_object_unsafe_cast(&fcx, did);
|
|
||||||
}
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
match self.do_check(fcx) {
|
match self.do_check(fcx) {
|
||||||
Ok(k) => {
|
Ok(k) => {
|
||||||
|
@ -741,14 +737,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_object_unsafe_cast(&self, fcx: &FnCtxt<'a, 'tcx>, did: DefId) {
|
|
||||||
let violations = fcx.tcx.object_safety_violations(did);
|
|
||||||
let mut err = report_object_safety_error(fcx.tcx, self.cast_span, did, violations);
|
|
||||||
err.note(&format!("required by cast to type '{}'", fcx.ty_to_string(self.cast_ty)));
|
|
||||||
err.emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks a cast, and report an error if one exists. In some cases, this
|
/// Checks a cast, and report an error if one exists. In some cases, this
|
||||||
/// can return Ok and create type errors in the fcx rather than returning
|
/// can return Ok and create type errors in the fcx rather than returning
|
||||||
/// directly. coercion-cast is handled in check instead of here.
|
/// directly. coercion-cast is handled in check instead of here.
|
||||||
|
|
|
@ -195,10 +195,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
debug!("coerce: unsize successful");
|
debug!("coerce: unsize successful");
|
||||||
return unsize;
|
return unsize;
|
||||||
}
|
}
|
||||||
Err(TypeError::ObjectUnsafeCoercion(did)) => {
|
|
||||||
debug!("coerce: unsize not object safe");
|
|
||||||
return Err(TypeError::ObjectUnsafeCoercion(did));
|
|
||||||
}
|
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
debug!(?error, "coerce: unsize failed");
|
debug!(?error, "coerce: unsize failed");
|
||||||
}
|
}
|
||||||
|
@ -498,27 +494,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
target = self.shallow_resolve(target);
|
target = self.shallow_resolve(target);
|
||||||
debug!(?source, ?target);
|
debug!(?source, ?target);
|
||||||
|
|
||||||
// These 'if' statements require some explanation.
|
// We don't apply any coercions incase either the source or target
|
||||||
// The `CoerceUnsized` trait is special - it is only
|
// aren't sufficiently well known but tend to instead just equate
|
||||||
// possible to write `impl CoerceUnsized<B> for A` where
|
// them both.
|
||||||
// A and B have 'matching' fields. This rules out the following
|
|
||||||
// two types of blanket impls:
|
|
||||||
//
|
|
||||||
// `impl<T> CoerceUnsized<T> for SomeType`
|
|
||||||
// `impl<T> CoerceUnsized<SomeType> for T`
|
|
||||||
//
|
|
||||||
// Both of these trigger a special `CoerceUnsized`-related error (E0376)
|
|
||||||
//
|
|
||||||
// We can take advantage of this fact to avoid performing unnecessary work.
|
|
||||||
// If either `source` or `target` is a type variable, then any applicable impl
|
|
||||||
// would need to be generic over the self-type (`impl<T> CoerceUnsized<SomeType> for T`)
|
|
||||||
// or generic over the `CoerceUnsized` type parameter (`impl<T> CoerceUnsized<T> for
|
|
||||||
// SomeType`).
|
|
||||||
//
|
|
||||||
// However, these are exactly the kinds of impls which are forbidden by
|
|
||||||
// the compiler! Therefore, we can be sure that coercion will always fail
|
|
||||||
// when either the source or target type is a type variable. This allows us
|
|
||||||
// to skip performing any trait selection, and immediately bail out.
|
|
||||||
if source.is_ty_var() {
|
if source.is_ty_var() {
|
||||||
debug!("coerce_unsized: source is a TyVar, bailing out");
|
debug!("coerce_unsized: source is a TyVar, bailing out");
|
||||||
return Err(TypeError::Mismatch);
|
return Err(TypeError::Mismatch);
|
||||||
|
@ -1101,15 +1079,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// Special-case that coercion alone cannot handle:
|
// Special-case that coercion alone cannot handle:
|
||||||
// Function items or non-capturing closures of differing IDs or InternalSubsts.
|
// Function items or non-capturing closures of differing IDs or InternalSubsts.
|
||||||
let (a_sig, b_sig) = {
|
let (a_sig, b_sig) = {
|
||||||
#[allow(rustc::usage_of_ty_tykind)]
|
let is_capturing_closure = |ty: Ty<'tcx>| {
|
||||||
let is_capturing_closure = |ty: &ty::TyKind<'tcx>| {
|
if let &ty::Closure(closure_def_id, _substs) = ty.kind() {
|
||||||
if let &ty::Closure(closure_def_id, _substs) = ty {
|
|
||||||
self.tcx.upvars_mentioned(closure_def_id.expect_local()).is_some()
|
self.tcx.upvars_mentioned(closure_def_id.expect_local()).is_some()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if is_capturing_closure(prev_ty.kind()) || is_capturing_closure(new_ty.kind()) {
|
if is_capturing_closure(prev_ty) || is_capturing_closure(new_ty) {
|
||||||
(None, None)
|
(None, None)
|
||||||
} else {
|
} else {
|
||||||
match (prev_ty.kind(), new_ty.kind()) {
|
match (prev_ty.kind(), new_ty.kind()) {
|
||||||
|
|
|
@ -343,10 +343,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
&mut orig_values,
|
&mut orig_values,
|
||||||
);
|
);
|
||||||
|
|
||||||
let steps = if mode == Mode::MethodCall {
|
let steps = match mode {
|
||||||
self.tcx.method_autoderef_steps(param_env_and_self_ty)
|
Mode::MethodCall => self.tcx.method_autoderef_steps(param_env_and_self_ty),
|
||||||
} else {
|
Mode::Path => self.probe(|_| {
|
||||||
self.probe(|_| {
|
|
||||||
// Mode::Path - the deref steps is "trivial". This turns
|
// Mode::Path - the deref steps is "trivial". This turns
|
||||||
// our CanonicalQuery into a "trivial" QueryResponse. This
|
// our CanonicalQuery into a "trivial" QueryResponse. This
|
||||||
// is a bit inefficient, but I don't think that writing
|
// is a bit inefficient, but I don't think that writing
|
||||||
|
@ -375,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
opt_bad_ty: None,
|
opt_bad_ty: None,
|
||||||
reached_recursion_limit: false,
|
reached_recursion_limit: false,
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
// If our autoderef loop had reached the recursion limit,
|
// If our autoderef loop had reached the recursion limit,
|
||||||
|
|
|
@ -1672,11 +1672,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match terr {
|
|
||||||
// Ignore msg for object safe coercion
|
|
||||||
// since E0038 message will be printed
|
|
||||||
TypeError::ObjectUnsafeCoercion(_) => {}
|
|
||||||
_ => {
|
|
||||||
let mut label_or_note = |span: Span, msg: &str| {
|
let mut label_or_note = |span: Span, msg: &str| {
|
||||||
if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
|
if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
|
||||||
diag.span_label(span, msg);
|
diag.span_label(span, msg);
|
||||||
|
@ -1704,8 +1699,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
label_or_note(span, &terr.to_string());
|
label_or_note(span, &terr.to_string());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Some((expected, found)) = expected_found {
|
if let Some((expected, found)) = expected_found {
|
||||||
let (expected_label, found_label, exp_found) = match exp_found {
|
let (expected_label, found_label, exp_found) = match exp_found {
|
||||||
Mismatch::Variable(ef) => (
|
Mismatch::Variable(ef) => (
|
||||||
|
@ -1875,9 +1869,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypeError::ObjectUnsafeCoercion(_) => {
|
|
||||||
diag.note_unsuccessful_coercion(found, expected);
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
debug!(
|
debug!(
|
||||||
"note_type_err: exp_found={:?}, expected={:?} found={:?}",
|
"note_type_err: exp_found={:?}, expected={:?} found={:?}",
|
||||||
|
@ -3122,7 +3113,6 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||||
TypeError::IntrinsicCast => {
|
TypeError::IntrinsicCast => {
|
||||||
Error0308("cannot coerce intrinsics to function pointers")
|
Error0308("cannot coerce intrinsics to function pointers")
|
||||||
}
|
}
|
||||||
TypeError::ObjectUnsafeCoercion(did) => Error0038(did),
|
|
||||||
_ => Error0308("mismatched types"),
|
_ => Error0308("mismatched types"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,6 @@ pub enum TypeError<'tcx> {
|
||||||
CyclicConst(ty::Const<'tcx>),
|
CyclicConst(ty::Const<'tcx>),
|
||||||
ProjectionMismatched(ExpectedFound<DefId>),
|
ProjectionMismatched(ExpectedFound<DefId>),
|
||||||
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>>),
|
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>>),
|
||||||
ObjectUnsafeCoercion(DefId),
|
|
||||||
ConstMismatch(ExpectedFound<ty::Const<'tcx>>),
|
ConstMismatch(ExpectedFound<ty::Const<'tcx>>),
|
||||||
|
|
||||||
IntrinsicCast,
|
IntrinsicCast,
|
||||||
|
@ -222,7 +221,6 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
|
||||||
f,
|
f,
|
||||||
"cannot coerce functions with `#[target_feature]` to safe function pointers"
|
"cannot coerce functions with `#[target_feature]` to safe function pointers"
|
||||||
),
|
),
|
||||||
ObjectUnsafeCoercion(_) => write!(f, "coercion to object-unsafe trait object"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,8 +247,7 @@ impl<'tcx> TypeError<'tcx> {
|
||||||
| ProjectionMismatched(_)
|
| ProjectionMismatched(_)
|
||||||
| ExistentialMismatch(_)
|
| ExistentialMismatch(_)
|
||||||
| ConstMismatch(_)
|
| ConstMismatch(_)
|
||||||
| IntrinsicCast
|
| IntrinsicCast => true,
|
||||||
| ObjectUnsafeCoercion(_) => true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue