1
Fork 0

Auto merge of #80105 - JohnTitor:rollup-8c030u5, r=JohnTitor

Rollup of 11 pull requests

Successful merges:

 - #79051 (Implement if-let match guards)
 - #79877 (Allow `since="TBD"` for rustc_deprecated)
 - #79882 (Fix issue #78496)
 - #80026 (expand-yaml-anchors: Make the output directory separator-insensitive)
 - #80039 (Remove unused `TyEncoder::tcx` required method)
 - #80069 (Test that `core::assert!` is valid)
 - #80072 (Fixed conflict with drop elaboration and coverage)
 - #80073 (Add support for target aliases)
 - #80082 (Revert #78790 - rust-src vendoring)
 - #80097 (Add `popcount` and `popcnt` as doc aliases for `count_ones` methods.)
 - #80103 (Remove docs for non-existent parameters in `rustc_expand`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2020-12-17 03:07:09 +00:00
commit 9b84d36a0b
64 changed files with 633 additions and 285 deletions

View file

@ -43,7 +43,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// FIXME(60707): Consider removing hack with principled solution.
self.check_expr_has_type_or_error(scrut, self.tcx.types.bool, |_| {})
} else {
self.demand_scrutinee_type(arms, scrut)
self.demand_scrutinee_type(scrut, arms_contain_ref_bindings(arms), arms.is_empty())
};
// If there are no arms, that is a diverging match; a special case.
@ -98,7 +98,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.diverges.set(Diverges::Maybe);
match g {
hir::Guard::If(e) => {
self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {})
self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {});
}
hir::Guard::IfLet(pat, e) => {
let scrutinee_ty = self.demand_scrutinee_type(
e,
pat.contains_explicit_ref_binding(),
false,
);
self.check_pat_top(&pat, scrutinee_ty, None, true);
}
};
}
@ -450,8 +458,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn demand_scrutinee_type(
&self,
arms: &'tcx [hir::Arm<'tcx>],
scrut: &'tcx hir::Expr<'tcx>,
contains_ref_bindings: Option<hir::Mutability>,
no_arms: bool,
) -> Ty<'tcx> {
// Not entirely obvious: if matches may create ref bindings, we want to
// use the *precise* type of the scrutinee, *not* some supertype, as
@ -505,17 +514,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// (once introduced) is populated by the time we get here.
//
// See #44848.
let contains_ref_bindings = arms
.iter()
.filter_map(|a| a.pat.contains_explicit_ref_binding())
.max_by_key(|m| match *m {
hir::Mutability::Mut => 1,
hir::Mutability::Not => 0,
});
if let Some(m) = contains_ref_bindings {
self.check_expr_with_needs(scrut, Needs::maybe_mut_place(m))
} else if arms.is_empty() {
} else if no_arms {
self.check_expr(scrut)
} else {
// ...but otherwise we want to use any supertype of the
@ -546,3 +547,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
fn arms_contain_ref_bindings(arms: &'tcx [hir::Arm<'tcx>]) -> Option<hir::Mutability> {
arms.iter().filter_map(|a| a.pat.contains_explicit_ref_binding()).max_by_key(|m| match *m {
hir::Mutability::Mut => 1,
hir::Mutability::Not => 0,
})
}

View file

@ -246,6 +246,10 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
Guard::If(ref e) => {
self.visit_expr(e);
}
Guard::IfLet(ref pat, ref e) => {
self.visit_pat(pat);
self.visit_expr(e);
}
}
let mut scope_var_ids =