summaryrefslogtreecommitdiff
path: root/compiler/rustc_ast_lowering/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast_lowering/src/lib.rs')
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs67
1 files changed, 44 insertions, 23 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index b5b28bf8e31..cd6614a54a4 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -247,7 +247,7 @@ enum ImplTraitContext {
in_trait: bool,
},
/// Impl trait in type aliases.
- TypeAliasesOpaqueTy,
+ TypeAliasesOpaqueTy { in_assoc_ty: bool },
/// `impl Trait` is unstably accepted in this position.
FeatureGated(ImplTraitPosition, Symbol),
/// `impl Trait` is not accepted in this position.
@@ -1190,13 +1190,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// parsing. We try to resolve that ambiguity by attempting resolution in both the
// type and value namespaces. If we resolved the path in the value namespace, we
// transform it into a generic const argument.
- TyKind::Path(qself, path) => {
+ TyKind::Path(None, path) => {
if let Some(res) = self
.resolver
.get_partial_res(ty.id)
.and_then(|partial_res| partial_res.full_res())
{
- if !res.matches_ns(Namespace::TypeNS) {
+ if !res.matches_ns(Namespace::TypeNS)
+ && path.is_potential_trivial_const_arg()
+ {
debug!(
"lower_generic_arg: Lowering type argument as const argument: {:?}",
ty,
@@ -1218,7 +1220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let path_expr = Expr {
id: ty.id,
- kind: ExprKind::Path(qself.clone(), path.clone()),
+ kind: ExprKind::Path(None, path.clone()),
span,
attrs: AttrVec::new(),
tokens: None,
@@ -1368,13 +1370,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {
GenericBound::Trait(
ty,
- TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
+ TraitBoundModifier::None
+ | TraitBoundModifier::MaybeConst
+ | TraitBoundModifier::Negative,
) => Some(this.lower_poly_trait_ref(ty, itctx)),
// `~const ?Bound` will cause an error during AST validation
// anyways, so treat it like `?Bound` as compilation proceeds.
GenericBound::Trait(
_,
- TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
+ TraitBoundModifier::Maybe
+ | TraitBoundModifier::MaybeConstMaybe
+ | TraitBoundModifier::MaybeConstNegative,
) => None,
GenericBound::Outlives(lifetime) => {
if lifetime_bound.is_none() {
@@ -1401,14 +1407,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
*in_trait,
itctx,
),
- ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait(
- span,
- hir::OpaqueTyOrigin::TyAlias,
- *def_node_id,
- bounds,
- false,
- itctx,
- ),
+ &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
+ .lower_opaque_impl_trait(
+ span,
+ hir::OpaqueTyOrigin::TyAlias { in_assoc_ty },
+ *def_node_id,
+ bounds,
+ false,
+ itctx,
+ ),
ImplTraitContext::Universal => {
let span = t.span;
self.create_def(
@@ -1473,6 +1480,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// Given a function definition like:
///
/// ```rust
+ /// use std::fmt::Debug;
+ ///
/// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {
/// x
/// }
@@ -1480,13 +1489,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
///
/// we will create a TAIT definition in the HIR like
///
- /// ```
+ /// ```rust,ignore (pseudo-Rust)
/// type TestReturn<'a, T, 'x> = impl Debug + 'x
/// ```
///
/// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:
///
- /// ```rust
+ /// ```rust,ignore (pseudo-Rust)
/// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>
/// ```
///
@@ -1526,13 +1535,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// If this came from a TAIT (as opposed to a function that returns an RPIT), we only want
// to capture the lifetimes that appear in the bounds. So visit the bounds to find out
// exactly which ones those are.
- let lifetimes_to_remap = if origin == hir::OpaqueTyOrigin::TyAlias {
- // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
- Vec::new()
- } else {
- // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
- // we only keep the lifetimes that appear in the `impl Debug` itself:
- lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds)
+ let lifetimes_to_remap = match origin {
+ hir::OpaqueTyOrigin::TyAlias { .. } => {
+ // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
+ Vec::new()
+ }
+ hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..) => {
+ // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
+ // we only keep the lifetimes that appear in the `impl Debug` itself:
+ lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds)
+ }
};
debug!(?lifetimes_to_remap);
@@ -2421,11 +2433,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
TraitBoundModifier::None => hir::TraitBoundModifier::None,
TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
+ TraitBoundModifier::Negative => {
+ if self.tcx.features().negative_bounds {
+ hir::TraitBoundModifier::Negative
+ } else {
+ hir::TraitBoundModifier::None
+ }
+ }
+
// `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
// placeholder for compilation to proceed.
TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
hir::TraitBoundModifier::Maybe
}
+ TraitBoundModifier::MaybeConstNegative => hir::TraitBoundModifier::MaybeConst,
}
}