@@ -1970,13 +1970,31 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
1970
1970
1971
1971
// Pick the first substitution that still contains inference variables as the one
1972
1972
// we're going to emit an error for. If there are none (see above), fall back to
1973
- // the substitution for `Self`.
1974
- let subst = {
1975
- let substs = data. trait_ref . substs ;
1976
- substs
1977
- . iter ( )
1978
- . find ( |s| s. has_infer_types_or_consts ( ) )
1979
- . unwrap_or_else ( || substs[ 0 ] )
1973
+ // a more general error.
1974
+ let subst = data. trait_ref . substs . iter ( ) . find ( |s| s. has_infer_types_or_consts ( ) ) ;
1975
+
1976
+ let mut err = if let Some ( subst) = subst {
1977
+ let impl_candidates = self
1978
+ . find_similar_impl_candidates ( trait_ref)
1979
+ . into_iter ( )
1980
+ . map ( |candidate| candidate. trait_ref )
1981
+ . collect ( ) ;
1982
+ self . emit_inference_failure_err (
1983
+ body_id,
1984
+ span,
1985
+ subst,
1986
+ impl_candidates,
1987
+ ErrorCode :: E0283 ,
1988
+ true ,
1989
+ )
1990
+ } else {
1991
+ struct_span_err ! (
1992
+ self . tcx. sess,
1993
+ span,
1994
+ E0283 ,
1995
+ "type annotations needed: cannot satisfy `{}`" ,
1996
+ predicate,
1997
+ )
1980
1998
} ;
1981
1999
1982
2000
// This is kind of a hack: it frequently happens that some earlier
@@ -1999,30 +2017,17 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
1999
2017
self . emit_inference_failure_err (
2000
2018
body_id,
2001
2019
span,
2002
- subst ,
2020
+ trait_ref . self_ty ( ) . skip_binder ( ) . into ( ) ,
2003
2021
vec ! [ ] ,
2004
2022
ErrorCode :: E0282 ,
2005
2023
false ,
2006
2024
)
2007
2025
. emit ( ) ;
2008
2026
}
2027
+ err. cancel ( ) ;
2009
2028
return ;
2010
2029
}
2011
2030
2012
- let impl_candidates = self
2013
- . find_similar_impl_candidates ( trait_ref)
2014
- . into_iter ( )
2015
- . map ( |candidate| candidate. trait_ref )
2016
- . collect ( ) ;
2017
- let mut err = self . emit_inference_failure_err (
2018
- body_id,
2019
- span,
2020
- subst,
2021
- impl_candidates,
2022
- ErrorCode :: E0283 ,
2023
- true ,
2024
- ) ;
2025
-
2026
2031
let obligation = Obligation :: new (
2027
2032
obligation. cause . clone ( ) ,
2028
2033
obligation. param_env ,
@@ -2136,24 +2141,28 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
2136
2141
)
2137
2142
}
2138
2143
ty:: PredicateKind :: Projection ( data) => {
2139
- let self_ty = data. projection_ty . self_ty ( ) ;
2140
- let term = data. term ;
2141
2144
if predicate. references_error ( ) || self . is_tainted_by_errors ( ) {
2142
2145
return ;
2143
2146
}
2144
- if self_ty. needs_infer ( ) && term. needs_infer ( ) {
2145
- // We do this for the `foo.collect()?` case to produce a suggestion.
2147
+ let subst = data
2148
+ . projection_ty
2149
+ . substs
2150
+ . iter ( )
2151
+ . chain ( Some ( data. term . into_arg ( ) ) )
2152
+ . find ( |g| g. has_infer_types_or_consts ( ) ) ;
2153
+ if let Some ( subst) = subst {
2146
2154
let mut err = self . emit_inference_failure_err (
2147
2155
body_id,
2148
2156
span,
2149
- self_ty . into ( ) ,
2157
+ subst ,
2150
2158
vec ! [ ] ,
2151
2159
ErrorCode :: E0284 ,
2152
2160
true ,
2153
2161
) ;
2154
2162
err. note ( & format ! ( "cannot satisfy `{}`" , predicate) ) ;
2155
2163
err
2156
2164
} else {
2165
+ // If we can't find a substitution, just print a generic error
2157
2166
let mut err = struct_span_err ! (
2158
2167
self . tcx. sess,
2159
2168
span,
0 commit comments