hir::ExprKind::Match(ref discr, arms, _) => {
let discr_place = return_if_err!(self.mc.cat_expr(discr));
- self.maybe_read_scrutinee(
+ return_if_err!(self.maybe_read_scrutinee(
discr,
discr_place.clone(),
arms.iter().map(|arm| arm.pat),
- );
+ ));
// treatment of the discriminant is handled while walking the arms.
for arm in arms {
discr: &Expr<'_>,
discr_place: PlaceWithHirId<'tcx>,
pats: impl Iterator<Item = &'t hir::Pat<'t>>,
- ) {
+ ) -> Result<(), ()> {
// Matching should not always be considered a use of the place, hence
// discr does not necessarily need to be borrowed.
// We only want to borrow discr if the pattern contain something other
let ExprUseVisitor { ref mc, body_owner: _, delegate: _ } = *self;
let mut needs_to_be_read = false;
for pat in pats {
- return_if_err!(mc.cat_pattern(discr_place.clone(), pat, |place, pat| {
+ mc.cat_pattern(discr_place.clone(), pat, |place, pat| {
match &pat.kind {
PatKind::Binding(.., opt_sub_pat) => {
// If the opt_sub_pat is None, than the binding does not count as
// examined
}
}
- }));
+ })?
}
if needs_to_be_read {
// that the discriminant has been initialized.
self.walk_expr(discr);
}
+ Ok(())
}
fn walk_local<F>(
f(self);
if let Some(els) = els {
// borrowing because we need to test the discriminant
- self.maybe_read_scrutinee(expr, expr_place.clone(), from_ref(pat).iter());
+ return_if_err!(self.maybe_read_scrutinee(
+ expr,
+ expr_place.clone(),
+ from_ref(pat).iter()
+ ));
self.walk_block(els)
}
self.walk_irrefutable_pat(&expr_place, &pat);
place_a: &Place<'tcx>,
place_b: &Place<'tcx>,
) -> PlaceAncestryRelation {
- // If Place A and Place B, don't start off from the same root variable, they are divergent.
+ // If Place A and Place B don't start off from the same root variable, they are divergent.
if place_a.base != place_b.base {
return PlaceAncestryRelation::Divergent;
}
--- /dev/null
+type Result<T, E = Error> = ::std::result::Result<T, E>;
+struct Error;
+
+trait ForEach {
+ type Input;
+ fn for_each<F, U>(self, f: F)
+ where
+ F: FnOnce(Self::Input) -> U;
+}
+
+impl<T> ForEach for A<T> {
+ type Input = T;
+ fn for_each<F, U>(self, f: F)
+ where
+ F: FnOnce(Self::Input) -> U,
+ {
+ todo!()
+ }
+}
+
+struct A<T>(T);
+
+fn main() {
+ let a = A(Result::Ok(Result::Ok(()))); //~ ERROR type annotations needed
+ a.for_each(|a: Result<_>| {
+ let f = || match a {
+ Ok(Ok(a)) => {}
+ Ok(Err(a)) => {}
+ Err(a) => {}
+ };
+ });
+}
--- /dev/null
+error[E0282]: type annotations needed for `A<std::result::Result<std::result::Result<(), E>, Error>>`
+ --> $DIR/issue-104649.rs:24:9
+ |
+LL | let a = A(Result::Ok(Result::Ok(())));
+ | ^
+ |
+help: consider giving `a` an explicit type, where the type for type parameter `E` is specified
+ |
+LL | let a: A<std::result::Result<std::result::Result<(), E>, Error>> = A(Result::Ok(Result::Ok(())));
+ | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.