mirror of https://github.com/rust-lang/rust.git
Make can_eq and can_sub return booleans
This commit is contained in:
parent
0b439b119b
commit
eb286dd070
|
@ -1144,7 +1144,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
LateBoundRegionConversionTime::FnCall,
|
LateBoundRegionConversionTime::FnCall,
|
||||||
tcx.fn_sig(method_did).subst(tcx, method_substs).input(0),
|
tcx.fn_sig(method_did).subst(tcx, method_substs).input(0),
|
||||||
)
|
)
|
||||||
&& infcx.can_eq(self.param_env, ty, self_ty).is_ok()
|
&& infcx.can_eq(self.param_env, ty, self_ty)
|
||||||
{
|
{
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
fn_call_span.shrink_to_lo(),
|
fn_call_span.shrink_to_lo(),
|
||||||
|
|
|
@ -2232,7 +2232,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
tcx.erase_regions(impl_.self_ty()),
|
tcx.erase_regions(impl_.self_ty()),
|
||||||
tcx.erase_regions(qself_ty),
|
tcx.erase_regions(qself_ty),
|
||||||
)
|
)
|
||||||
.is_ok()
|
|
||||||
})
|
})
|
||||||
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
|
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
|
||||||
})
|
})
|
||||||
|
|
|
@ -1116,7 +1116,7 @@ fn compare_self_type<'tcx>(
|
||||||
|
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty);
|
let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty);
|
||||||
let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok();
|
let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty);
|
||||||
match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
|
match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
|
||||||
ExplicitSelf::ByValue => "self".to_owned(),
|
ExplicitSelf::ByValue => "self".to_owned(),
|
||||||
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
|
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
|
||||||
|
|
|
@ -1716,7 +1716,7 @@ fn receiver_is_valid<'tcx>(
|
||||||
let cause =
|
let cause =
|
||||||
ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver);
|
ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver);
|
||||||
|
|
||||||
let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty).is_ok();
|
let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty);
|
||||||
|
|
||||||
// `self: Self` is always valid.
|
// `self: Self` is always valid.
|
||||||
if can_eq_self(receiver_ty) {
|
if can_eq_self(receiver_ty) {
|
||||||
|
|
|
@ -321,7 +321,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let mut param_args = FxHashMap::default();
|
let mut param_args = FxHashMap::default();
|
||||||
let mut param_expected = FxHashMap::default();
|
let mut param_expected = FxHashMap::default();
|
||||||
let mut param_found = FxHashMap::default();
|
let mut param_found = FxHashMap::default();
|
||||||
if self.can_eq(self.param_env, ty, found).is_ok() {
|
if self.can_eq(self.param_env, ty, found) {
|
||||||
// We only point at the first place where the found type was inferred.
|
// We only point at the first place where the found type was inferred.
|
||||||
for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() {
|
for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() {
|
||||||
if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() {
|
if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() {
|
||||||
|
@ -369,7 +369,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
for (param, (arg, arg_ty)) in param_args.iter() {
|
for (param, (arg, arg_ty)) in param_args.iter() {
|
||||||
let Some(expected) = param_expected.get(param) else { continue; };
|
let Some(expected) = param_expected.get(param) else { continue; };
|
||||||
let Some(found) = param_found.get(param) else { continue; };
|
let Some(found) = param_found.get(param) else { continue; };
|
||||||
if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; }
|
if !self.can_eq(self.param_env, *arg_ty, *found) { continue; }
|
||||||
self.emit_coerce_suggestions(err, arg, *found, *expected, None, None);
|
self.emit_coerce_suggestions(err, arg, *found, *expected, None, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
if ty != prev
|
if ty != prev
|
||||||
&& param_args.is_empty()
|
&& param_args.is_empty()
|
||||||
&& self.can_eq(self.param_env, ty, found).is_ok()
|
&& self.can_eq(self.param_env, ty, found)
|
||||||
{
|
{
|
||||||
// We only point at the first place where the found type was inferred.
|
// We only point at the first place where the found type was inferred.
|
||||||
if !segment.ident.span.overlaps(mismatch_span) {
|
if !segment.ident.span.overlaps(mismatch_span) {
|
||||||
|
@ -401,7 +401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
if ty != prev
|
if ty != prev
|
||||||
&& let Some(span) = prev_span
|
&& let Some(span) = prev_span
|
||||||
&& self.can_eq(self.param_env, ty, found).is_ok()
|
&& self.can_eq(self.param_env, ty, found)
|
||||||
{
|
{
|
||||||
// We only point at the first place where the found type was inferred.
|
// We only point at the first place where the found type was inferred.
|
||||||
// We use the *previous* span because if the type is known *here* it means
|
// We use the *previous* span because if the type is known *here* it means
|
||||||
|
@ -764,7 +764,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if let ty::Adt(expected_adt, substs) = expected.kind() {
|
if let ty::Adt(expected_adt, substs) = expected.kind() {
|
||||||
if let hir::ExprKind::Field(base, ident) = expr.kind {
|
if let hir::ExprKind::Field(base, ident) = expr.kind {
|
||||||
let base_ty = self.typeck_results.borrow().expr_ty(base);
|
let base_ty = self.typeck_results.borrow().expr_ty(base);
|
||||||
if self.can_eq(self.param_env, base_ty, expected).is_ok()
|
if self.can_eq(self.param_env, base_ty, expected)
|
||||||
&& let Some(base_span) = base.span.find_ancestor_inside(expr.span)
|
&& let Some(base_span) = base.span.find_ancestor_inside(expr.span)
|
||||||
{
|
{
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
|
@ -1357,7 +1357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr),
|
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr),
|
||||||
_,
|
_,
|
||||||
&ty::Ref(_, checked, _),
|
&ty::Ref(_, checked, _),
|
||||||
) if self.can_sub(self.param_env, checked, expected).is_ok() => {
|
) if self.can_sub(self.param_env, checked, expected) => {
|
||||||
// We have `&T`, check if what was expected was `T`. If so,
|
// We have `&T`, check if what was expected was `T`. If so,
|
||||||
// we may want to suggest removing a `&`.
|
// we may want to suggest removing a `&`.
|
||||||
if sm.is_imported(expr.span) {
|
if sm.is_imported(expr.span) {
|
||||||
|
@ -2003,7 +2003,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
let hir::StmtKind::Semi(tail_expr) = stmt.kind else { return; };
|
let hir::StmtKind::Semi(tail_expr) = stmt.kind else { return; };
|
||||||
let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else { return; };
|
let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else { return; };
|
||||||
if self.can_eq(self.param_env, expected_ty, ty).is_ok() {
|
if self.can_eq(self.param_env, expected_ty, ty) {
|
||||||
err.span_suggestion_short(
|
err.span_suggestion_short(
|
||||||
stmt.span.with_lo(tail_expr.span.hi()),
|
stmt.span.with_lo(tail_expr.span.hi()),
|
||||||
"remove this semicolon",
|
"remove this semicolon",
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let expr_inner_ty = substs.type_at(0);
|
let expr_inner_ty = substs.type_at(0);
|
||||||
let expected_inner_ty = expected_substs.type_at(0);
|
let expected_inner_ty = expected_substs.type_at(0);
|
||||||
if let ty::Ref(_, ty, hir::Mutability::Not) = expr_inner_ty.kind()
|
if let ty::Ref(_, ty, hir::Mutability::Not) = expr_inner_ty.kind()
|
||||||
&& self.can_eq(self.param_env, *ty, expected_inner_ty).is_ok()
|
&& self.can_eq(self.param_env, *ty, expected_inner_ty)
|
||||||
{
|
{
|
||||||
let def_path = self.tcx.def_path_str(adt_def.did());
|
let def_path = self.tcx.def_path_str(adt_def.did());
|
||||||
if self.type_is_copy_modulo_regions(self.param_env, *ty, expr.span) {
|
if self.type_is_copy_modulo_regions(self.param_env, *ty, expr.span) {
|
||||||
|
@ -1054,7 +1054,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if let Some(result_did) = self.tcx.get_diagnostic_item(sym::Result)
|
if let Some(result_did) = self.tcx.get_diagnostic_item(sym::Result)
|
||||||
&& adt_def.did() == result_did
|
&& adt_def.did() == result_did
|
||||||
// Check that the error types are equal
|
// Check that the error types are equal
|
||||||
&& self.can_eq(self.param_env, substs.type_at(1), expected_substs.type_at(1)).is_ok()
|
&& self.can_eq(self.param_env, substs.type_at(1), expected_substs.type_at(1))
|
||||||
{
|
{
|
||||||
return suggest_copied_or_cloned();
|
return suggest_copied_or_cloned();
|
||||||
} else if let Some(option_did) = self.tcx.get_diagnostic_item(sym::Option)
|
} else if let Some(option_did) = self.tcx.get_diagnostic_item(sym::Option)
|
||||||
|
|
|
@ -936,7 +936,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.can_sub(self.param_env, fty.output(), expected).is_ok()
|
self.can_sub(self.param_env, fty.output(), expected)
|
||||||
}),
|
}),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?;
|
self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?;
|
||||||
if let Some(expr) = ti.origin_expr {
|
if let Some(expr) = ti.origin_expr {
|
||||||
self.suggest_fn_call(&mut diag, expr, expected, |output| {
|
self.suggest_fn_call(&mut diag, expr, expected, |output| {
|
||||||
self.can_eq(self.param_env, output, actual).is_ok()
|
self.can_eq(self.param_env, output, actual)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some(diag)
|
Some(diag)
|
||||||
|
@ -675,7 +675,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
) {
|
) {
|
||||||
match (expected.kind(), actual.kind(), ba) {
|
match (expected.kind(), actual.kind(), ba) {
|
||||||
(ty::Ref(_, inner_ty, _), _, hir::BindingAnnotation::NONE)
|
(ty::Ref(_, inner_ty, _), _, hir::BindingAnnotation::NONE)
|
||||||
if self.can_eq(self.param_env, *inner_ty, actual).is_ok() =>
|
if self.can_eq(self.param_env, *inner_ty, actual) =>
|
||||||
{
|
{
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span.shrink_to_lo(),
|
span.shrink_to_lo(),
|
||||||
|
@ -685,7 +685,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
(_, ty::Ref(_, inner_ty, _), hir::BindingAnnotation::REF)
|
(_, ty::Ref(_, inner_ty, _), hir::BindingAnnotation::REF)
|
||||||
if self.can_eq(self.param_env, expected, *inner_ty).is_ok() =>
|
if self.can_eq(self.param_env, expected, *inner_ty) =>
|
||||||
{
|
{
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span.with_hi(span.lo() + BytePos(4)),
|
span.with_hi(span.lo() + BytePos(4)),
|
||||||
|
|
|
@ -576,7 +576,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
tcx.impl_defaultness(item.id.owner_id)
|
tcx.impl_defaultness(item.id.owner_id)
|
||||||
{
|
{
|
||||||
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
|
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
|
||||||
if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() {
|
if self.infcx.can_eq(param_env, assoc_ty, found) {
|
||||||
diag.span_label(
|
diag.span_label(
|
||||||
item.span,
|
item.span,
|
||||||
"associated type defaults can't be assumed inside the \
|
"associated type defaults can't be assumed inside the \
|
||||||
|
@ -598,7 +598,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
if let hir::AssocItemKind::Type = item.kind {
|
if let hir::AssocItemKind::Type = item.kind {
|
||||||
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
|
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
|
||||||
|
|
||||||
if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() {
|
if self.infcx.can_eq(param_env, assoc_ty, found) {
|
||||||
diag.span_label(item.span, "expected this associated type");
|
diag.span_label(item.span, "expected this associated type");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -880,30 +880,20 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup);
|
self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx>
|
pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
||||||
where
|
where
|
||||||
T: at::ToTrace<'tcx>,
|
T: at::ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
let origin = &ObligationCause::dummy();
|
let origin = &ObligationCause::dummy();
|
||||||
self.probe(|_| {
|
self.probe(|_| self.at(origin, param_env).sub(a, b).is_ok())
|
||||||
self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| {
|
|
||||||
// Ignore obligations, since we are unrolling
|
|
||||||
// everything anyway.
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx>
|
pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
||||||
where
|
where
|
||||||
T: at::ToTrace<'tcx>,
|
T: at::ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
let origin = &ObligationCause::dummy();
|
let origin = &ObligationCause::dummy();
|
||||||
self.probe(|_| {
|
self.probe(|_| self.at(origin, param_env).eq(a, b).is_ok())
|
||||||
self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| {
|
|
||||||
// Ignore obligations, since we are unrolling
|
|
||||||
// everything anyway.
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
|
|
|
@ -1629,7 +1629,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
// Eventually I'll need to implement param-env-aware
|
// Eventually I'll need to implement param-env-aware
|
||||||
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
|
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
|
||||||
let param_env = ty::ParamEnv::empty();
|
let param_env = ty::ParamEnv::empty();
|
||||||
if self.can_sub(param_env, error, implication).is_ok() {
|
if self.can_sub(param_env, error, implication) {
|
||||||
debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication);
|
debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
|
|
||||||
let impl_self_ty = impl_trait_ref.self_ty();
|
let impl_self_ty = impl_trait_ref.self_ty();
|
||||||
|
|
||||||
if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) {
|
if self.can_eq(param_env, trait_self_ty, impl_self_ty) {
|
||||||
self_match_impls.push((def_id, impl_substs));
|
self_match_impls.push((def_id, impl_substs));
|
||||||
|
|
||||||
if iter::zip(
|
if iter::zip(
|
||||||
|
|
|
@ -748,10 +748,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
let real_ty = real_trait_pred.self_ty();
|
let real_ty = real_trait_pred.self_ty();
|
||||||
// We `erase_late_bound_regions` here because `make_subregion` does not handle
|
// We `erase_late_bound_regions` here because `make_subregion` does not handle
|
||||||
// `ReLateBound`, and we don't particularly care about the regions.
|
// `ReLateBound`, and we don't particularly care about the regions.
|
||||||
if self
|
if !self.can_eq(
|
||||||
.can_eq(obligation.param_env, self.tcx.erase_late_bound_regions(real_ty), arg_ty)
|
obligation.param_env,
|
||||||
.is_err()
|
self.tcx.erase_late_bound_regions(real_ty),
|
||||||
{
|
arg_ty,
|
||||||
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3690,7 +3691,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
let Some((span, (assoc, ty))) = entry else { continue; };
|
let Some((span, (assoc, ty))) = entry else { continue; };
|
||||||
if primary_spans.is_empty() || type_diffs.iter().any(|diff| {
|
if primary_spans.is_empty() || type_diffs.iter().any(|diff| {
|
||||||
let Sorts(expected_found) = diff else { return false; };
|
let Sorts(expected_found) = diff else { return false; };
|
||||||
self.can_eq(param_env, expected_found.found, ty).is_ok()
|
self.can_eq(param_env, expected_found.found, ty)
|
||||||
}) {
|
}) {
|
||||||
// FIXME: this doesn't quite work for `Iterator::collect`
|
// FIXME: this doesn't quite work for `Iterator::collect`
|
||||||
// because we have `Vec<i32>` and `()`, but we'd want `i32`
|
// because we have `Vec<i32>` and `()`, but we'd want `i32`
|
||||||
|
@ -3717,10 +3718,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
let ty_str = with_forced_trimmed_paths!(self.ty_to_string(ty));
|
let ty_str = with_forced_trimmed_paths!(self.ty_to_string(ty));
|
||||||
|
|
||||||
let assoc = with_forced_trimmed_paths!(self.tcx.def_path_str(assoc));
|
let assoc = with_forced_trimmed_paths!(self.tcx.def_path_str(assoc));
|
||||||
if self.can_eq(param_env, ty, *prev_ty).is_err() {
|
if !self.can_eq(param_env, ty, *prev_ty) {
|
||||||
if type_diffs.iter().any(|diff| {
|
if type_diffs.iter().any(|diff| {
|
||||||
let Sorts(expected_found) = diff else { return false; };
|
let Sorts(expected_found) = diff else { return false; };
|
||||||
self.can_eq(param_env, expected_found.found, ty).is_ok()
|
self.can_eq(param_env, expected_found.found, ty)
|
||||||
}) {
|
}) {
|
||||||
primary_spans.push(span);
|
primary_spans.push(span);
|
||||||
}
|
}
|
||||||
|
@ -3868,7 +3869,7 @@ fn hint_missing_borrow<'tcx>(
|
||||||
let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg);
|
let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg);
|
||||||
let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg);
|
let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg);
|
||||||
|
|
||||||
if infcx.can_eq(param_env, found_ty, expected_ty).is_ok() {
|
if infcx.can_eq(param_env, found_ty, expected_ty) {
|
||||||
// FIXME: This could handle more exotic cases like mutability mismatches too!
|
// FIXME: This could handle more exotic cases like mutability mismatches too!
|
||||||
if found_refs.len() < expected_refs.len()
|
if found_refs.len() < expected_refs.len()
|
||||||
&& found_refs[..] == expected_refs[expected_refs.len() - found_refs.len()..]
|
&& found_refs[..] == expected_refs[expected_refs.len() - found_refs.len()..]
|
||||||
|
|
Loading…
Reference in New Issue