@@ -61,8 +61,8 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
6161use rustc_hir:: definitions:: DefPathData ;
6262use rustc_hir:: { ConstArg , GenericArg , ItemLocalId , ParamName , TraitCandidate } ;
6363use rustc_index:: vec:: { Idx , IndexVec } ;
64+ use rustc_middle:: span_bug;
6465use rustc_middle:: ty:: { ResolverAstLowering , TyCtxt } ;
65- use rustc_middle:: { bug, span_bug} ;
6666use rustc_session:: parse:: feature_err;
6767use rustc_span:: hygiene:: MacroKind ;
6868use rustc_span:: source_map:: DesugaringKind ;
@@ -512,11 +512,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
512512 self . resolver . node_id_to_def_id . get ( & node) . map ( |local_def_id| * local_def_id)
513513 }
514514
515- fn orig_local_def_id ( & self , node : NodeId ) -> LocalDefId {
516- self . orig_opt_local_def_id ( node)
517- . unwrap_or_else ( || panic ! ( "no entry for node id: `{:?}`" , node) )
518- }
519-
520515 /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
521516 /// resolver (if any), after applying any remapping from `get_remapped_def_id`.
522517 ///
@@ -1457,17 +1452,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14571452 // frequently opened issues show.
14581453 let opaque_ty_span = self . mark_span_with_reason ( DesugaringKind :: OpaqueTy , span, None ) ;
14591454
1460- let opaque_ty_def_id = match origin {
1461- hir:: OpaqueTyOrigin :: TyAlias => self . create_def (
1462- self . current_hir_id_owner . def_id ,
1463- opaque_ty_node_id,
1464- DefPathData :: ImplTrait ,
1465- ) ,
1466- hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) => {
1467- self . create_def ( fn_def_id, opaque_ty_node_id, DefPathData :: ImplTrait )
1468- }
1469- hir:: OpaqueTyOrigin :: AsyncFn ( ..) => bug ! ( "unreachable" ) ,
1470- } ;
1455+ let opaque_ty_def_id = self . create_def (
1456+ self . current_hir_id_owner . def_id ,
1457+ opaque_ty_node_id,
1458+ DefPathData :: ImplTrait ,
1459+ ) ;
14711460 debug ! ( ?opaque_ty_def_id) ;
14721461
14731462 // Contains the new lifetime definitions created for the TAIT (if any).
@@ -1831,221 +1820,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18311820 let opaque_ty_def_id = self . local_def_id ( opaque_ty_node_id) ;
18321821 let fn_def_id = self . local_def_id ( fn_node_id) ;
18331822
1834- // When we create the opaque type for this async fn, it is going to have
1835- // to capture all the lifetimes involved in the signature (including in the
1836- // return type). This is done by introducing lifetime parameters for:
1837- //
1838- // - all the explicitly declared lifetimes from the impl and function itself;
1839- // - all the elided lifetimes in the fn arguments;
1840- // - all the elided lifetimes in the return type.
1841- //
1842- // So for example in this snippet:
1843- //
1844- // ```rust
1845- // impl<'a> Foo<'a> {
1846- // async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
1847- // // ^ '0 ^ '1 ^ '2
1848- // // elided lifetimes used below
1849- // }
1850- // }
1851- // ```
1852- //
1853- // we would create an opaque type like:
1854- //
1855- // ```
1856- // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
1857- // ```
1858- //
1859- // and we would then desugar `bar` to the equivalent of:
1860- //
1861- // ```rust
1862- // impl<'a> Foo<'a> {
1863- // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
1864- // }
1865- // ```
1866- //
1867- // Note that the final parameter to `Bar` is `'_`, not `'2` --
1868- // this is because the elided lifetimes from the return type
1869- // should be figured out using the ordinary elision rules, and
1870- // this desugaring achieves that.
1871-
1872- // Calculate all the lifetimes that should be captured
1873- // by the opaque type. This should include all in-scope
1874- // lifetime parameters, including those defined in-band.
1875-
1876- // Contains the new lifetime definitions created for the TAIT (if any) generated for the
1877- // return type.
1878- let mut collected_lifetimes = Vec :: new ( ) ;
1879- let mut new_remapping = FxHashMap :: default ( ) ;
1880-
1881- let extra_lifetime_params = self . resolver . take_extra_lifetime_params ( opaque_ty_node_id) ;
1882- debug ! ( ?extra_lifetime_params) ;
1883- for ( ident, outer_node_id, outer_res) in extra_lifetime_params {
1884- let outer_def_id = self . orig_local_def_id ( outer_node_id) ;
1885- let inner_node_id = self . next_node_id ( ) ;
1886-
1887- // Add a definition for the in scope lifetime def.
1888- let inner_def_id = self . create_def (
1889- opaque_ty_def_id,
1890- inner_node_id,
1891- DefPathData :: LifetimeNs ( ident. name ) ,
1892- ) ;
1893- new_remapping. insert ( outer_def_id, inner_def_id) ;
1894-
1895- let inner_res = match outer_res {
1896- // Input lifetime like `'a`:
1897- LifetimeRes :: Param { param, .. } => {
1898- LifetimeRes :: Param { param, binder : fn_node_id }
1899- }
1900- // Input lifetime like `'1`:
1901- LifetimeRes :: Fresh { param, .. } => {
1902- LifetimeRes :: Fresh { param, binder : fn_node_id }
1903- }
1904- LifetimeRes :: Static | LifetimeRes :: Error => continue ,
1905- res => {
1906- panic ! (
1907- "Unexpected lifetime resolution {:?} for {:?} at {:?}" ,
1908- res, ident, ident. span
1909- )
1910- }
1911- } ;
1912-
1913- let lifetime = Lifetime { id : outer_node_id, ident } ;
1914- collected_lifetimes. push ( ( inner_node_id, lifetime, Some ( inner_res) ) ) ;
1915- }
1916-
1917- debug ! ( ?collected_lifetimes) ;
1918-
1919- // We only want to capture the lifetimes that appear in the bounds. So visit the bounds to
1920- // find out exactly which ones those are.
1921- // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
1922- // we only keep the lifetimes that appear in the `impl Debug` itself:
1923- let lifetimes_to_remap = lifetime_collector:: lifetimes_in_ret_ty ( & self . resolver , output) ;
1924- debug ! ( ?lifetimes_to_remap) ;
1925-
19261823 self . with_hir_id_owner ( opaque_ty_node_id, |this| {
1927- // If this opaque type is only capturing a subset of the lifetimes (those that appear
1928- // in bounds), then create the new lifetime parameters required and create a mapping
1929- // from the old `'a` (on the function) to the new `'a` (on the opaque type).
1930- collected_lifetimes . extend (
1931- this . create_lifetime_defs (
1932- opaque_ty_def_id ,
1933- & lifetimes_to_remap ,
1934- & mut new_remapping ,
1935- )
1936- . into_iter ( )
1937- . map ( | ( new_node_id , lifetime ) | ( new_node_id , lifetime , None ) ) ,
1824+ let future_bound = this . lower_async_fn_output_type_to_future_bound (
1825+ output ,
1826+ span ,
1827+ if in_trait && !this . tcx . features ( ) . return_position_impl_trait_in_trait {
1828+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: TraitReturn )
1829+ } else {
1830+ ImplTraitContext :: ReturnPositionOpaqueTy {
1831+ origin : hir :: OpaqueTyOrigin :: FnReturn ( fn_def_id ) ,
1832+ in_trait ,
1833+ }
1834+ } ,
19381835 ) ;
1939- debug ! ( ?collected_lifetimes) ;
1940- debug ! ( ?new_remapping) ;
1941-
1942- // Install the remapping from old to new (if any):
1943- this. with_remapping ( new_remapping, |this| {
1944- // We have to be careful to get elision right here. The
1945- // idea is that we create a lifetime parameter for each
1946- // lifetime in the return type. So, given a return type
1947- // like `async fn foo(..) -> &[&u32]`, we lower to `impl
1948- // Future<Output = &'1 [ &'2 u32 ]>`.
1949- //
1950- // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1951- // hence the elision takes place at the fn site.
1952- let future_bound = this. lower_async_fn_output_type_to_future_bound (
1953- output,
1954- span,
1955- if in_trait && !this. tcx . features ( ) . return_position_impl_trait_in_trait {
1956- ImplTraitContext :: Disallowed ( ImplTraitPosition :: TraitReturn )
1957- } else {
1958- ImplTraitContext :: ReturnPositionOpaqueTy {
1959- origin : hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id) ,
1960- in_trait,
1961- }
1962- } ,
1963- ) ;
1964-
1965- let generic_params = this. arena . alloc_from_iter ( collected_lifetimes. iter ( ) . map (
1966- |& ( new_node_id, lifetime, _) | {
1967- let hir_id = this. lower_node_id ( new_node_id) ;
1968- debug_assert_ne ! ( this. opt_local_def_id( new_node_id) , None ) ;
1969-
1970- let ( name, kind) = if lifetime. ident . name == kw:: UnderscoreLifetime {
1971- ( hir:: ParamName :: Fresh , hir:: LifetimeParamKind :: Elided )
1972- } else {
1973- (
1974- hir:: ParamName :: Plain ( lifetime. ident ) ,
1975- hir:: LifetimeParamKind :: Explicit ,
1976- )
1977- } ;
1978-
1979- hir:: GenericParam {
1980- hir_id,
1981- name,
1982- span : lifetime. ident . span ,
1983- pure_wrt_drop : false ,
1984- kind : hir:: GenericParamKind :: Lifetime { kind } ,
1985- colon_span : None ,
1986- }
1987- } ,
1988- ) ) ;
1989- debug ! ( "lower_async_fn_ret_ty: generic_params={:#?}" , generic_params) ;
19901836
1991- let opaque_ty_item = hir:: OpaqueTy {
1992- generics : this. arena . alloc ( hir:: Generics {
1993- params : generic_params ,
1994- predicates : & [ ] ,
1995- has_where_clause_predicates : false ,
1996- where_clause_span : this. lower_span ( span) ,
1997- span : this. lower_span ( span) ,
1998- } ) ,
1999- bounds : arena_vec ! [ this; future_bound] ,
2000- origin : hir:: OpaqueTyOrigin :: AsyncFn ( fn_def_id) ,
2001- in_trait,
2002- } ;
1837+ let opaque_ty_item = hir:: OpaqueTy {
1838+ generics : this. arena . alloc ( hir:: Generics {
1839+ params : & [ ] ,
1840+ predicates : & [ ] ,
1841+ has_where_clause_predicates : false ,
1842+ where_clause_span : this. lower_span ( span) ,
1843+ span : this. lower_span ( span) ,
1844+ } ) ,
1845+ bounds : arena_vec ! [ this; future_bound] ,
1846+ origin : hir:: OpaqueTyOrigin :: AsyncFn ( fn_def_id) ,
1847+ in_trait,
1848+ } ;
20031849
2004- trace ! ( "exist ty from async fn def id: {:#?}" , opaque_ty_def_id) ;
2005- this. generate_opaque_type ( opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
2006- } )
1850+ trace ! ( "exist ty from async fn def id: {:#?}" , opaque_ty_def_id) ;
1851+ this. generate_opaque_type ( opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
20071852 } ) ;
20081853
2009- // As documented above, we need to create the lifetime
2010- // arguments to our opaque type. Continuing with our example,
2011- // we're creating the type arguments for the return type:
2012- //
2013- // ```
2014- // Bar<'a, 'b, '0, '1, '_>
2015- // ```
2016- //
2017- // For the "input" lifetime parameters, we wish to create
2018- // references to the parameters themselves, including the
2019- // "implicit" ones created from parameter types (`'a`, `'b`,
2020- // '`0`, `'1`).
2021- //
2022- // For the "output" lifetime parameters, we just want to
2023- // generate `'_`.
2024- let generic_args = self . arena . alloc_from_iter ( collected_lifetimes. into_iter ( ) . map (
2025- |( _, lifetime, res) | {
2026- let id = self . next_node_id ( ) ;
2027- let span = lifetime. ident . span ;
2028-
2029- let ident = if lifetime. ident . name == kw:: UnderscoreLifetime {
2030- Ident :: with_dummy_span ( kw:: UnderscoreLifetime )
2031- } else {
2032- lifetime. ident
2033- } ;
2034-
2035- let res = res. unwrap_or (
2036- self . resolver . get_lifetime_res ( lifetime. id ) . unwrap_or ( LifetimeRes :: Error ) ,
2037- ) ;
2038- hir:: GenericArg :: Lifetime ( self . new_named_lifetime_with_res ( id, span, ident, res) )
2039- } ,
2040- ) ) ;
2041-
2042- // Create the `Foo<...>` reference itself. Note that the `type
2043- // Foo = impl Trait` is, internally, created as a child of the
2044- // async fn, so the *type parameters* are inherited. It's
2045- // only the lifetime parameters that we must supply.
20461854 let opaque_ty_ref = hir:: TyKind :: OpaqueDef (
20471855 hir:: ItemId { def_id : hir:: OwnerId { def_id : opaque_ty_def_id } } ,
2048- generic_args ,
1856+ & [ ] ,
20491857 in_trait,
20501858 ) ;
20511859 let opaque_ty = self . ty ( opaque_ty_span, opaque_ty_ref) ;
0 commit comments