Skip to content

[alternative approach] Introduce const-qualified paths #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,16 @@ impl GenBlockKind {
pub struct QSelf {
pub ty: P<Ty>,

/// The constness of the trait (under feature `const_trait_impl`).
///
/// * `<Type as Trait>::AssocTy`: `BoundConstness::Never`
/// * `<Type as const Trait>::AssocTy`: `BoundConstness::Always`
/// * `<Type as ~const Trait>::AssocTy`: `BoundConstness::Maybe`
// FIXME(effects): This is the most convenient place to put this information but
// it doesn't make much sense from a conceptual viewpoint since it doesn't have
// much to do with the self type.
pub constness: BoundConstness,

/// The span of `a::b::Trait` in a path like `<Vec<T> as
/// a::b::Trait>::AssociatedItem`; in the case where `position ==
/// 0`, this is an empty span.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path

pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<P<QSelf>>, vis: &mut T) {
visit_opt(qself, |qself| {
let QSelf { ty, path_span, position: _ } = &mut **qself;
let QSelf { ty, constness: _, path_span, position: _ } = &mut **qself;
vis.visit_ty(ty);
vis.visit_span(path_span);
})
Expand Down
36 changes: 17 additions & 19 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,36 +200,35 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ItemKind::Const(ty, generics, body_id)
}
ItemKind::Fn(box Fn {
sig: FnSig { decl, header, span: fn_sig_span },
sig: FnSig { decl: ast_decl, header, span: fn_sig_span },
generics,
body,
..
}) => {
self.with_new_scopes(ident.span, |this| {
// Note: we don't need to change the return type from `T` to
// `impl Future<Output = T>` here because lower_body
// only cares about the input argument patterns in the function
// declaration (decl), not the return types.
let coroutine_kind = header.coroutine_kind;
let body_id = this.lower_maybe_coroutine_body(
span,
hir_id,
decl,
coroutine_kind,
body.as_deref(),
);

// We lower the generics before we lower the body since the body can bind the host
// effect param via qualified paths of the form `<Type as ~const Trait>::AssocType`.
let itctx = ImplTraitContext::Universal;
let (generics, decl) =
this.lower_generics(generics, header.constness, id, &itctx, |this| {
this.lower_fn_decl(
decl,
ast_decl,
id,
*fn_sig_span,
FnDeclKind::Fn,
coroutine_kind,
header.coroutine_kind,
)
});
// Note: We don't need to change the return type from `T` to `impl Future<Output = T>`
// here because `lower_body` only cares about the input argument patterns in the function
// declaration `decl`, not the return types.
let body_id = this.lower_maybe_coroutine_body(
span,
hir_id,
ast_decl,
header.coroutine_kind,
body.as_deref(),
);
let sig = hir::FnSig {
decl,
header: this.lower_fn_header(*header),
Expand Down Expand Up @@ -600,9 +599,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.host_param_id = generics
.params
.iter()
.find(|param| {
matches!(param.kind, hir::GenericParamKind::Const { is_host_effect: true, .. })
})
.rev()
.find(|param| param.is_host_effect())
.map(|param| param.def_id);
}

Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// constness of the impl/bound if this is a trait path
constness: Option<ast::BoundConstness>,
) -> hir::QPath<'hir> {
// FIXME(effects): The name isn't great.
let trait_constness = qself.as_ref().map(|q| q.constness);
let qself_position = qself.as_ref().map(|q| q.position);
let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));

Expand Down Expand Up @@ -76,8 +78,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
param_mode,
parenthesized_generic_args,
itctx,
// if this is the last segment, add constness to the trait path
if i == proj_start - 1 { constness } else { None },
// If this is the last segment, add constness to the trait path.
// FIXME(effects): Is it possible that both constnesses are Some?
if i == proj_start - 1 { constness } else { trait_constness },
)
},
)),
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,9 @@ impl<'a> State<'a> {
if qself.position > 0 {
self.space();
self.word_space("as");
if qself.constness != ast::BoundConstness::Never {
self.word_space(qself.constness.as_str());
}
let depth = path.segments.len() - qself.position;
self.print_path(path, false, depth);
}
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,10 @@ impl GenericArg<'_> {
GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => true,
}
}

pub fn is_desugared_from_effects(&self) -> bool {
matches!(self, GenericArg::Const(ConstArg { is_desugared_from_effects: true, .. }))
}
}

#[derive(Debug, Clone, Copy, HashStable_Generic)]
Expand Down Expand Up @@ -381,10 +385,8 @@ impl<'hir> GenericArgs<'hir> {
pub fn num_generic_params(&self) -> usize {
self.args
.iter()
.filter(|arg| match arg {
GenericArg::Lifetime(_)
| GenericArg::Const(ConstArg { is_desugared_from_effects: true, .. }) => false,
_ => true,
.filter(|arg| {
!matches!(arg, GenericArg::Lifetime(_)) && !arg.is_desugared_from_effects()
})
.count()
}
Expand Down Expand Up @@ -518,6 +520,10 @@ impl<'hir> GenericParam<'hir> {
pub fn is_elided_lifetime(&self) -> bool {
matches!(self.kind, GenericParamKind::Lifetime { kind: LifetimeParamKind::Elided })
}

pub fn is_host_effect(&self) -> bool {
matches!(self.kind, GenericParamKind::Const { is_host_effect: true, .. })
}
}

/// Records where the generic parameter originated from.
Expand Down
Loading