Skip to content

Commit

Permalink
Rollup merge of #104890 - lcnr:small-cleanup, r=fee1-dead
Browse files Browse the repository at this point in the history
small method code cleanup
  • Loading branch information
Dylan-DPC authored Nov 28, 2022
2 parents 79fe15c + 99c3dda commit 8a84dd8
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 92 deletions.
16 changes: 10 additions & 6 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Hack: we know that there are traits implementing Fn for &F
// where F:Fn and so forth. In the particular case of types
// like `x: &mut FnMut()`, if there is a call `x()`, we would
// normally translate to `FnMut::call_mut(&mut x, ())`, but
// that winds up requiring `mut x: &mut FnMut()`. A little
// over the top. The simplest fix by far is to just ignore
// this case and deref again, so we wind up with
// `FnMut::call_mut(&mut *x, ())`.
// like `f: &mut FnMut()`, if there is a call `f()`, we would
// normally translate to `FnMut::call_mut(&mut f, ())`, but
// that winds up potentially requiring the user to mark their
// variable as `mut` which feels unnecessary and unexpected.
//
// 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 => {
return None;
}
Expand Down
12 changes: 0 additions & 12 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::sym;
use rustc_span::Span;
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
/// a function context.
Expand Down Expand Up @@ -727,9 +726,6 @@ impl<'a, 'tcx> CastCheck<'tcx> {
debug!(" -> CoercionCast");
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(_) => {
match self.do_check(fcx) {
Ok(k) => {
Expand All @@ -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
/// can return Ok and create type errors in the fcx rather than returning
/// directly. coercion-cast is handled in check instead of here.
Expand Down
35 changes: 6 additions & 29 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
debug!("coerce: unsize successful");
return unsize;
}
Err(TypeError::ObjectUnsafeCoercion(did)) => {
debug!("coerce: unsize not object safe");
return Err(TypeError::ObjectUnsafeCoercion(did));
}
Err(error) => {
debug!(?error, "coerce: unsize failed");
}
Expand Down Expand Up @@ -498,27 +494,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
target = self.shallow_resolve(target);
debug!(?source, ?target);

// These 'if' statements require some explanation.
// The `CoerceUnsized` trait is special - it is only
// possible to write `impl CoerceUnsized<B> for A` where
// 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.
// We don't apply any coercions incase either the source or target
// aren't sufficiently well known but tend to instead just equate
// them both.
if source.is_ty_var() {
debug!("coerce_unsized: source is a TyVar, bailing out");
return Err(TypeError::Mismatch);
Expand Down Expand Up @@ -1101,15 +1079,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Special-case that coercion alone cannot handle:
// Function items or non-capturing closures of differing IDs or InternalSubsts.
let (a_sig, b_sig) = {
#[allow(rustc::usage_of_ty_tykind)]
let is_capturing_closure = |ty: &ty::TyKind<'tcx>| {
if let &ty::Closure(closure_def_id, _substs) = ty {
let is_capturing_closure = |ty: Ty<'tcx>| {
if let &ty::Closure(closure_def_id, _substs) = ty.kind() {
self.tcx.upvars_mentioned(closure_def_id.expect_local()).is_some()
} else {
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)
} else {
match (prev_ty.kind(), new_ty.kind()) {
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&mut orig_values,
);

let steps = if mode == Mode::MethodCall {
self.tcx.method_autoderef_steps(param_env_and_self_ty)
} else {
self.probe(|_| {
let steps = match mode {
Mode::MethodCall => self.tcx.method_autoderef_steps(param_env_and_self_ty),
Mode::Path => self.probe(|_| {
// Mode::Path - the deref steps is "trivial". This turns
// our CanonicalQuery into a "trivial" QueryResponse. This
// is a bit inefficient, but I don't think that writing
Expand Down Expand Up @@ -375,7 +374,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
opt_bad_ty: None,
reached_recursion_limit: false,
}
})
}),
};

// If our autoderef loop had reached the recursion limit,
Expand Down
62 changes: 26 additions & 36 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1672,40 +1672,34 @@ 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| {
if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
diag.span_label(span, msg);
} else {
diag.span_note(span, msg);
}
};
if let Some((sp, msg)) = secondary_span {
if swap_secondary_and_primary {
let terr = if let Some(infer::ValuePairs::Terms(infer::ExpectedFound {
expected,
..
})) = values
{
format!("expected this to be `{}`", expected)
} else {
terr.to_string()
};
label_or_note(sp, &terr);
label_or_note(span, &msg);
} else {
label_or_note(span, &terr.to_string());
label_or_note(sp, &msg);
}
} else {
label_or_note(span, &terr.to_string());
}
let mut label_or_note = |span: Span, msg: &str| {
if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() {
diag.span_label(span, msg);
} else {
diag.span_note(span, msg);
}
};
if let Some((sp, msg)) = secondary_span {
if swap_secondary_and_primary {
let terr = if let Some(infer::ValuePairs::Terms(infer::ExpectedFound {
expected,
..
})) = values
{
format!("expected this to be `{}`", expected)
} else {
terr.to_string()
};
label_or_note(sp, &terr);
label_or_note(span, &msg);
} else {
label_or_note(span, &terr.to_string());
label_or_note(sp, &msg);
}
} else {
label_or_note(span, &terr.to_string());
}

if let Some((expected, found)) = expected_found {
let (expected_label, found_label, exp_found) = match exp_found {
Mismatch::Variable(ef) => (
Expand Down Expand Up @@ -1875,9 +1869,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);
}
}
TypeError::ObjectUnsafeCoercion(_) => {
diag.note_unsuccessful_coercion(found, expected);
}
_ => {
debug!(
"note_type_err: exp_found={:?}, expected={:?} found={:?}",
Expand Down Expand Up @@ -3122,7 +3113,6 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
TypeError::IntrinsicCast => {
Error0308("cannot coerce intrinsics to function pointers")
}
TypeError::ObjectUnsafeCoercion(did) => Error0038(did),
_ => Error0308("mismatched types"),
},
}
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ pub enum TypeError<'tcx> {
CyclicConst(ty::Const<'tcx>),
ProjectionMismatched(ExpectedFound<DefId>),
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>>),
ObjectUnsafeCoercion(DefId),
ConstMismatch(ExpectedFound<ty::Const<'tcx>>),

IntrinsicCast,
Expand Down Expand Up @@ -222,7 +221,6 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
f,
"cannot coerce functions with `#[target_feature]` to safe function pointers"
),
ObjectUnsafeCoercion(_) => write!(f, "coercion to object-unsafe trait object"),
}
}
}
Expand All @@ -249,8 +247,7 @@ impl<'tcx> TypeError<'tcx> {
| ProjectionMismatched(_)
| ExistentialMismatch(_)
| ConstMismatch(_)
| IntrinsicCast
| ObjectUnsafeCoercion(_) => true,
| IntrinsicCast => true,
}
}
}
Expand Down

0 comments on commit 8a84dd8

Please sign in to comment.