From 6711313f76b712271b10080067ebd4e0034b6be8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 1 Jul 2022 01:30:48 +0000 Subject: [PATCH] Move Sized check before first error is created --- .../src/traits/error_reporting/mod.rs | 62 +++++++++---------- .../branches3.stderr | 12 ++-- .../closures_in_branches.stderr | 3 +- .../ui/type-alias-impl-trait/fallback.stderr | 2 + 4 files changed, 38 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 3201ea1e2715..fa56219b409d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1958,6 +1958,37 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { if predicate.references_error() { return; } + + // This is kind of a hack: it frequently happens that some earlier + // error prevents types from being fully inferred, and then we get + // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we + // could just skip over all checks where the self-ty is an + // inference variable, but I was afraid that there might be an + // inference variable created, registered as an obligation, and + // then never forced by writeback, and hence by skipping here we'd + // be ignoring the fact that we don't KNOW the type works + // out. Though even that would probably be harmless, given that + // we're only talking about builtin traits, which are known to be + // inhabited. We used to check for `self.tcx.sess.has_errors()` to + // avoid inundating the user with unnecessary errors, but we now + // check upstream for type errors and don't add the obligations to + // begin with in those cases. + if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { + if !self.is_tainted_by_errors() { + self.emit_inference_failure_err( + body_id, + span, + trait_ref.self_ty().skip_binder().into(), + vec![], + ErrorCode::E0282, + false, + ) + .emit(); + } + return; + } + // Typically, this ambiguity should only happen if // there are unresolved type inference variables // (otherwise it would suggest a coherence @@ -1997,37 +2028,6 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ) }; - // This is kind of a hack: it frequently happens that some earlier - // error prevents types from being fully inferred, and then we get - // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we - // could just skip over all checks where the self-ty is an - // inference variable, but I was afraid that there might be an - // inference variable created, registered as an obligation, and - // then never forced by writeback, and hence by skipping here we'd - // be ignoring the fact that we don't KNOW the type works - // out. Though even that would probably be harmless, given that - // we're only talking about builtin traits, which are known to be - // inhabited. We used to check for `self.tcx.sess.has_errors()` to - // avoid inundating the user with unnecessary errors, but we now - // check upstream for type errors and don't add the obligations to - // begin with in those cases. - if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { - if !self.is_tainted_by_errors() { - self.emit_inference_failure_err( - body_id, - span, - trait_ref.self_ty().skip_binder().into(), - vec![], - ErrorCode::E0282, - false, - ) - .emit(); - } - err.cancel(); - return; - } - let obligation = Obligation::new( obligation.cause.clone(), obligation.param_env, diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr b/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr index 77ce1d48480a..420104e526d9 100644 --- a/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr +++ b/src/test/ui/lazy-type-alias-impl-trait/branches3.stderr @@ -2,9 +2,8 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:8:10 | LL | |s| s.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |s: _| s.len() @@ -14,9 +13,8 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:15:10 | LL | |s| s.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |s: _| s.len() @@ -26,9 +24,8 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:23:10 | LL | |s| s.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |s: _| s.len() @@ -38,9 +35,8 @@ error[E0282]: type annotations needed --> $DIR/branches3.rs:30:10 | LL | |s| s.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |s: _| s.len() diff --git a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr index 08f7d8c9f2db..48b7946ea820 100644 --- a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr +++ b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr @@ -2,9 +2,8 @@ error[E0282]: type annotations needed --> $DIR/closures_in_branches.rs:7:10 | LL | |x| x.len() - | ^ + | ^ - type must be known at this point | - = note: type must be known at this point help: consider giving this closure parameter an explicit type | LL | |x: _| x.len() diff --git a/src/test/ui/type-alias-impl-trait/fallback.stderr b/src/test/ui/type-alias-impl-trait/fallback.stderr index e009399a60ab..e767bfdb08b6 100644 --- a/src/test/ui/type-alias-impl-trait/fallback.stderr +++ b/src/test/ui/type-alias-impl-trait/fallback.stderr @@ -1,6 +1,8 @@ error[E0283]: type annotations needed --> $DIR/fallback.rs:24:5 | +LL | fn unconstrained_foo() -> Wrapper { + | ------------ type must be known at this point LL | Wrapper::Second | ^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the enum `Wrapper` |