@@ -29,8 +29,9 @@ use rustc_span::Span;
2929use smallvec:: { smallvec, SmallVec } ;
3030
3131use log:: debug;
32+ use rustc_span:: source_map:: { respan, Spanned } ;
3233use std:: collections:: BTreeSet ;
33- use std:: mem:: replace;
34+ use std:: mem:: { replace, take } ;
3435
3536mod diagnostics;
3637crate mod lifetimes;
@@ -234,6 +235,13 @@ impl<'a> PathSource<'a> {
234235 }
235236 }
236237
238+ fn is_call ( self ) -> bool {
239+ match self {
240+ PathSource :: Expr ( Some ( & Expr { kind : ExprKind :: Call ( ..) , .. } ) ) => true ,
241+ _ => false ,
242+ }
243+ }
244+
237245 crate fn is_expected ( self , res : Res ) -> bool {
238246 match self {
239247 PathSource :: Type => match res {
@@ -1620,14 +1628,83 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
16201628
16211629 let report_errors = |this : & mut Self , res : Option < Res > | {
16221630 let ( err, candidates) = this. smart_resolve_report_errors ( path, span, source, res) ;
1631+
16231632 let def_id = this. parent_scope . module . normal_ancestor_id ;
1624- let better = res. is_some ( ) ;
1633+ let instead = res. is_some ( ) ;
16251634 let suggestion =
16261635 if res. is_none ( ) { this. report_missing_type_error ( path) } else { None } ;
1627- this. r . use_injections . push ( UseError { err, candidates, def_id, better, suggestion } ) ;
1636+
1637+ this. r . use_injections . push ( UseError { err, candidates, def_id, instead, suggestion } ) ;
1638+
16281639 PartialRes :: new ( Res :: Err )
16291640 } ;
16301641
1642+ // For paths originating from calls (like in `HashMap::new()`), tries
1643+ // to enrich the plain `failed to resolve: ...` message with hints
1644+ // about possible missing imports.
1645+ //
1646+ // Similar thing, for types, happens in `report_errors` above.
1647+ let report_errors_for_call = |this : & mut Self , parent_err : Spanned < ResolutionError < ' a > > | {
1648+ if !source. is_call ( ) {
1649+ return Some ( parent_err) ;
1650+ }
1651+
1652+ // Before we start looking for candidates, we have to get our hands
1653+ // on the type user is trying to perform invocation on; basically:
1654+ // we're transforming `HashMap::new` into just `HashMap`
1655+ let path = if let Some ( ( _, path) ) = path. split_last ( ) {
1656+ path
1657+ } else {
1658+ return Some ( parent_err) ;
1659+ } ;
1660+
1661+ let ( mut err, candidates) =
1662+ this. smart_resolve_report_errors ( path, span, PathSource :: Type , None ) ;
1663+
1664+ if candidates. is_empty ( ) {
1665+ err. cancel ( ) ;
1666+ return Some ( parent_err) ;
1667+ }
1668+
1669+ // There are two different error messages user might receive at
1670+ // this point:
1671+ // - E0412 cannot find type `{}` in this scope
1672+ // - E0433 failed to resolve: use of undeclared type or module `{}`
1673+ //
1674+ // The first one is emitted for paths in type-position, and the
1675+ // latter one - for paths in expression-position.
1676+ //
1677+ // Thus (since we're in expression-position at this point), not to
1678+ // confuse the user, we want to keep the *message* from E04322 (so
1679+ // `parent_err`), but we want *hints* from E0412 (so `err`).
1680+ //
1681+ // And that's what happens below - we're just mixing both messages
1682+ // into a single one.
1683+ let mut parent_err = this. r . into_struct_error ( parent_err. span , parent_err. node ) ;
1684+
1685+ parent_err. cancel ( ) ;
1686+
1687+ err. message = take ( & mut parent_err. message ) ;
1688+ err. code = take ( & mut parent_err. code ) ;
1689+ err. children = take ( & mut parent_err. children ) ;
1690+
1691+ drop ( parent_err) ;
1692+
1693+ let def_id = this. parent_scope . module . normal_ancestor_id ;
1694+
1695+ this. r . use_injections . push ( UseError {
1696+ err,
1697+ candidates,
1698+ def_id,
1699+ instead : false ,
1700+ suggestion : None ,
1701+ } ) ;
1702+
1703+ // We don't return `Some(parent_err)` here, because the error will
1704+ // be already printed as part of the `use` injections
1705+ None
1706+ } ;
1707+
16311708 let partial_res = match self . resolve_qpath_anywhere (
16321709 id,
16331710 qself,
@@ -1637,14 +1714,15 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
16371714 source. defer_to_typeck ( ) ,
16381715 crate_lint,
16391716 ) {
1640- Some ( partial_res) if partial_res. unresolved_segments ( ) == 0 => {
1717+ Ok ( Some ( partial_res) ) if partial_res. unresolved_segments ( ) == 0 => {
16411718 if is_expected ( partial_res. base_res ( ) ) || partial_res. base_res ( ) == Res :: Err {
16421719 partial_res
16431720 } else {
16441721 report_errors ( self , Some ( partial_res. base_res ( ) ) )
16451722 }
16461723 }
1647- Some ( partial_res) if source. defer_to_typeck ( ) => {
1724+
1725+ Ok ( Some ( partial_res) ) if source. defer_to_typeck ( ) => {
16481726 // Not fully resolved associated item `T::A::B` or `<T as Tr>::A::B`
16491727 // or `<T>::A::B`. If `B` should be resolved in value namespace then
16501728 // it needs to be added to the trait map.
@@ -1655,25 +1733,34 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
16551733 }
16561734
16571735 let mut std_path = vec ! [ Segment :: from_ident( Ident :: with_dummy_span( sym:: std) ) ] ;
1736+
16581737 std_path. extend ( path) ;
1738+
16591739 if self . r . primitive_type_table . primitive_types . contains_key ( & path[ 0 ] . ident . name ) {
1660- let cl = CrateLint :: No ;
1661- let ns = Some ( ns) ;
16621740 if let PathResult :: Module ( _) | PathResult :: NonModule ( _) =
1663- self . resolve_path ( & std_path, ns , false , span, cl )
1741+ self . resolve_path ( & std_path, Some ( ns ) , false , span, CrateLint :: No )
16641742 {
1665- // check if we wrote `str::from_utf8` instead of `std::str::from_utf8`
1743+ // Check if we wrote `str::from_utf8` instead of `std::str::from_utf8`
16661744 let item_span =
16671745 path. iter ( ) . last ( ) . map ( |segment| segment. ident . span ) . unwrap_or ( span) ;
1668- debug ! ( "accessed item from `std` submodule as a bare type {:?}" , std_path ) ;
1746+
16691747 let mut hm = self . r . session . confused_type_with_std_module . borrow_mut ( ) ;
16701748 hm. insert ( item_span, span) ;
1671- // In some places (E0223) we only have access to the full path
16721749 hm. insert ( span, span) ;
16731750 }
16741751 }
1752+
16751753 partial_res
16761754 }
1755+
1756+ Err ( err) => {
1757+ if let Some ( err) = report_errors_for_call ( self , err) {
1758+ self . r . report_error ( err. span , err. node ) ;
1759+ }
1760+
1761+ PartialRes :: new ( Res :: Err )
1762+ }
1763+
16771764 _ => report_errors ( self , None ) ,
16781765 } ;
16791766
@@ -1682,6 +1769,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
16821769 // Avoid recording definition of `A::B` in `<T as A>::B::C`.
16831770 self . r . record_partial_res ( id, partial_res) ;
16841771 }
1772+
16851773 partial_res
16861774 }
16871775
@@ -1711,17 +1799,16 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
17111799 span : Span ,
17121800 defer_to_typeck : bool ,
17131801 crate_lint : CrateLint ,
1714- ) -> Option < PartialRes > {
1802+ ) -> Result < Option < PartialRes > , Spanned < ResolutionError < ' a > > > {
17151803 let mut fin_res = None ;
1804+
17161805 for ( i, ns) in [ primary_ns, TypeNS , ValueNS ] . iter ( ) . cloned ( ) . enumerate ( ) {
17171806 if i == 0 || ns != primary_ns {
1718- match self . resolve_qpath ( id, qself, path, ns, span, crate_lint) {
1719- // If defer_to_typeck, then resolution > no resolution,
1720- // otherwise full resolution > partial resolution > no resolution.
1807+ match self . resolve_qpath ( id, qself, path, ns, span, crate_lint) ? {
17211808 Some ( partial_res)
17221809 if partial_res. unresolved_segments ( ) == 0 || defer_to_typeck =>
17231810 {
1724- return Some ( partial_res) ;
1811+ return Ok ( Some ( partial_res) ) ;
17251812 }
17261813 partial_res => {
17271814 if fin_res. is_none ( ) {
@@ -1732,19 +1819,19 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
17321819 }
17331820 }
17341821
1735- // `MacroNS`
17361822 assert ! ( primary_ns != MacroNS ) ;
1823+
17371824 if qself. is_none ( ) {
17381825 let path_seg = |seg : & Segment | PathSegment :: from_ident ( seg. ident ) ;
17391826 let path = Path { segments : path. iter ( ) . map ( path_seg) . collect ( ) , span } ;
17401827 if let Ok ( ( _, res) ) =
17411828 self . r . resolve_macro_path ( & path, None , & self . parent_scope , false , false )
17421829 {
1743- return Some ( PartialRes :: new ( res) ) ;
1830+ return Ok ( Some ( PartialRes :: new ( res) ) ) ;
17441831 }
17451832 }
17461833
1747- fin_res
1834+ Ok ( fin_res)
17481835 }
17491836
17501837 /// Handles paths that may refer to associated items.
@@ -1756,7 +1843,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
17561843 ns : Namespace ,
17571844 span : Span ,
17581845 crate_lint : CrateLint ,
1759- ) -> Option < PartialRes > {
1846+ ) -> Result < Option < PartialRes > , Spanned < ResolutionError < ' a > > > {
17601847 debug ! (
17611848 "resolve_qpath(id={:?}, qself={:?}, path={:?}, ns={:?}, span={:?})" ,
17621849 id, qself, path, ns, span,
@@ -1767,10 +1854,10 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
17671854 // This is a case like `<T>::B`, where there is no
17681855 // trait to resolve. In that case, we leave the `B`
17691856 // segment to be resolved by type-check.
1770- return Some ( PartialRes :: with_unresolved_segments (
1857+ return Ok ( Some ( PartialRes :: with_unresolved_segments (
17711858 Res :: Def ( DefKind :: Mod , DefId :: local ( CRATE_DEF_INDEX ) ) ,
17721859 path. len ( ) ,
1773- ) ) ;
1860+ ) ) ) ;
17741861 }
17751862
17761863 // Make sure `A::B` in `<T as A::B>::C` is a trait item.
@@ -1800,10 +1887,10 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
18001887 // The remaining segments (the `C` in our example) will
18011888 // have to be resolved by type-check, since that requires doing
18021889 // trait resolution.
1803- return Some ( PartialRes :: with_unresolved_segments (
1890+ return Ok ( Some ( PartialRes :: with_unresolved_segments (
18041891 partial_res. base_res ( ) ,
18051892 partial_res. unresolved_segments ( ) + path. len ( ) - qself. position - 1 ,
1806- ) ) ;
1893+ ) ) ) ;
18071894 }
18081895
18091896 let result = match self . resolve_path ( & path, Some ( ns) , true , span, crate_lint) {
@@ -1838,11 +1925,10 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
18381925 PartialRes :: new ( module. res ( ) . unwrap ( ) )
18391926 }
18401927 PathResult :: Failed { is_error_from_last_segment : false , span, label, suggestion } => {
1841- self . r . report_error ( span, ResolutionError :: FailedToResolve { label, suggestion } ) ;
1842- PartialRes :: new ( Res :: Err )
1928+ return Err ( respan ( span, ResolutionError :: FailedToResolve { label, suggestion } ) ) ;
18431929 }
1844- PathResult :: Module ( ..) | PathResult :: Failed { .. } => return None ,
1845- PathResult :: Indeterminate => bug ! ( "indetermined path result in resolve_qpath" ) ,
1930+ PathResult :: Module ( ..) | PathResult :: Failed { .. } => return Ok ( None ) ,
1931+ PathResult :: Indeterminate => bug ! ( "indeterminate path result in resolve_qpath" ) ,
18461932 } ;
18471933
18481934 if path. len ( ) > 1
@@ -1862,7 +1948,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
18621948 PathResult :: Module ( ModuleOrUniformRoot :: Module ( module) ) => {
18631949 module. res ( ) . unwrap ( )
18641950 }
1865- _ => return Some ( result) ,
1951+ _ => return Ok ( Some ( result) ) ,
18661952 }
18671953 } ;
18681954 if result. base_res ( ) == unqualified_result {
@@ -1871,7 +1957,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
18711957 }
18721958 }
18731959
1874- Some ( result)
1960+ Ok ( Some ( result) )
18751961 }
18761962
18771963 fn with_resolved_label ( & mut self , label : Option < Label > , id : NodeId , f : impl FnOnce ( & mut Self ) ) {
0 commit comments