Skip to content
Merged
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
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {

fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir, AmbigArg>) {
self.insert(
const_arg.as_unambig_ct().span(),
const_arg.as_unambig_ct().span,
const_arg.hir_id,
Node::ConstArg(const_arg.as_unambig_ct()),
);
Expand Down
63 changes: 53 additions & 10 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2285,8 +2285,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// `ExprKind::Paren(ExprKind::Underscore)` and should also be lowered to `GenericArg::Infer`
match c.value.peel_parens().kind {
ExprKind::Underscore => {
let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
let ct_kind = hir::ConstArgKind::Infer(());
self.arena.alloc(hir::ConstArg {
hir_id: self.lower_node_id(c.id),
kind: ct_kind,
span: self.lower_span(c.value.span),
})
}
_ => self.lower_anon_const_to_const_arg_and_alloc(c),
}
Expand Down Expand Up @@ -2356,7 +2360,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::ConstArgKind::Anon(ct)
};

self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind })
self.arena.alloc(hir::ConstArg {
hir_id: self.next_id(),
kind: ct_kind,
span: self.lower_span(span),
})
}

fn lower_const_item_rhs(
Expand All @@ -2373,9 +2381,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let const_arg = ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Error(
DUMMY_SP,
self.dcx().span_delayed_bug(DUMMY_SP, "no block"),
),
span: DUMMY_SP,
};
hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg))
}
Expand All @@ -2388,13 +2396,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

#[instrument(level = "debug", skip(self), ret)]
fn lower_expr_to_const_arg_direct(&mut self, expr: &Expr) -> hir::ConstArg<'hir> {
let span = self.lower_span(expr.span);

let overly_complex_const = |this: &mut Self| {
let e = this.dcx().struct_span_err(
expr.span,
"complex const arguments must be placed inside of a `const` block",
);

ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(expr.span, e.emit()) }
ConstArg { hir_id: this.next_id(), kind: hir::ConstArgKind::Error(e.emit()), span }
};

match &expr.kind {
Expand Down Expand Up @@ -2425,8 +2435,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::TupleCall(qpath, lowered_args),
span,
}
}
ExprKind::Tup(exprs) => {
let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| {
let expr = if let ExprKind::ConstBlock(anon_const) = &expr.kind {
let def_id = self.local_def_id(anon_const.id);
let def_kind = self.tcx.def_kind(def_id);
assert_eq!(DefKind::AnonConst, def_kind);

self.lower_anon_const_to_const_arg(anon_const)
} else {
self.lower_expr_to_const_arg_direct(&expr)
};

&*self.arena.alloc(expr)
}));

ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Tup(exprs), span }
}
ExprKind::Path(qself, path) => {
let qpath = self.lower_qpath(
expr.id,
Expand All @@ -2439,7 +2467,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
None,
);

ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath) }
ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath), span }
}
ExprKind::Struct(se) => {
let path = self.lower_qpath(
Expand Down Expand Up @@ -2480,11 +2508,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
})
}));

ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Struct(path, fields) }
ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Struct(path, fields),
span,
}
}
ExprKind::Underscore => ConstArg {
hir_id: self.lower_node_id(expr.id),
kind: hir::ConstArgKind::Infer(expr.span, ()),
kind: hir::ConstArgKind::Infer(()),
span,
},
ExprKind::Block(block, _) => {
if let [stmt] = block.stmts.as_slice()
Expand All @@ -2495,6 +2528,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
| ExprKind::Path(..)
| ExprKind::Struct(..)
| ExprKind::Call(..)
| ExprKind::Tup(..)
)
{
return self.lower_expr_to_const_arg_direct(expr);
Expand Down Expand Up @@ -2528,7 +2562,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
return match anon.mgca_disambiguation {
MgcaDisambiguation::AnonConst => {
let lowered_anon = self.lower_anon_const_to_anon_const(anon);
ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Anon(lowered_anon),
span: lowered_anon.span,
}
}
MgcaDisambiguation::Direct => self.lower_expr_to_const_arg_direct(&anon.value),
};
Expand Down Expand Up @@ -2565,11 +2603,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
return ConstArg {
hir_id: self.lower_node_id(anon.id),
kind: hir::ConstArgKind::Path(qpath),
span: self.lower_span(expr.span),
};
}

let lowered_anon = self.lower_anon_const_to_anon_const(anon);
ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Anon(lowered_anon) }
ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Anon(lowered_anon),
span: self.lower_span(expr.span),
}
}

/// See [`hir::ConstArg`] for when to use this function vs
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.arena.alloc(hir::ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Anon(self.arena.alloc(anon_const)),
span,
})
}

Expand Down Expand Up @@ -557,6 +558,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
})
});
let hir_id = self.next_id();
self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id })
self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id, span })
}
}
23 changes: 7 additions & 16 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ impl<'hir> ConstItemRhs<'hir> {
pub fn span<'tcx>(&self, tcx: impl crate::intravisit::HirTyCtxt<'tcx>) -> Span {
match self {
ConstItemRhs::Body(body_id) => tcx.hir_body(*body_id).value.span,
ConstItemRhs::TypeConst(ct_arg) => ct_arg.span(),
ConstItemRhs::TypeConst(ct_arg) => ct_arg.span,
}
}
}
Expand All @@ -447,6 +447,7 @@ pub struct ConstArg<'hir, Unambig = ()> {
#[stable_hasher(ignore)]
pub hir_id: HirId,
pub kind: ConstArgKind<'hir, Unambig>,
pub span: Span,
}

impl<'hir> ConstArg<'hir, AmbigArg> {
Expand Down Expand Up @@ -475,7 +476,7 @@ impl<'hir> ConstArg<'hir> {
/// Functions accepting ambiguous consts will not handle the [`ConstArgKind::Infer`] variant, if
/// infer consts are relevant to you then care should be taken to handle them separately.
pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
if let ConstArgKind::Infer(_, ()) = self.kind {
if let ConstArgKind::Infer(()) = self.kind {
return None;
}

Expand All @@ -494,23 +495,13 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> {
_ => None,
}
}

pub fn span(&self) -> Span {
match self.kind {
ConstArgKind::Struct(path, _) => path.span(),
ConstArgKind::Path(path) => path.span(),
ConstArgKind::TupleCall(path, _) => path.span(),
ConstArgKind::Anon(anon) => anon.span,
ConstArgKind::Error(span, _) => span,
ConstArgKind::Infer(span, _) => span,
}
}
}

/// See [`ConstArg`].
#[derive(Clone, Copy, Debug, HashStable_Generic)]
#[repr(u8, C)]
pub enum ConstArgKind<'hir, Unambig = ()> {
Tup(&'hir [&'hir ConstArg<'hir, Unambig>]),
/// **Note:** Currently this is only used for bare const params
/// (`N` where `fn foo<const N: usize>(...)`),
/// not paths to any const (`N` where `const N: usize = ...`).
Expand All @@ -523,10 +514,10 @@ pub enum ConstArgKind<'hir, Unambig = ()> {
/// Tuple constructor variant
TupleCall(QPath<'hir>, &'hir [&'hir ConstArg<'hir>]),
/// Error const
Error(Span, ErrorGuaranteed),
Error(ErrorGuaranteed),
/// This variant is not always used to represent inference consts, sometimes
/// [`GenericArg::Infer`] is used instead.
Infer(Span, Unambig),
Infer(Unambig),
}

#[derive(Clone, Copy, Debug, HashStable_Generic)]
Expand Down Expand Up @@ -572,7 +563,7 @@ impl GenericArg<'_> {
match self {
GenericArg::Lifetime(l) => l.ident.span,
GenericArg::Type(t) => t.span,
GenericArg::Const(c) => c.span(),
GenericArg::Const(c) => c.span,
GenericArg::Infer(i) => i.span,
}
}
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_hir/src/hir/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ define_tests! {
cast_ptr TyKind Ptr { 0: MutTy { ty: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never }, mutbl: Mutability::Not }}
cast_array TyKind Array {
0: &Ty { span: DUMMY_SP, hir_id: HirId::INVALID, kind: TyKind::Never },
1: &ConstArg { hir_id: HirId::INVALID, kind: ConstArgKind::Anon(&AnonConst {
1: &ConstArg {
hir_id: HirId::INVALID,
def_id: LocalDefId { local_def_index: DefIndex::ZERO },
body: BodyId { hir_id: HirId::INVALID },
kind: ConstArgKind::Anon(&AnonConst {
hir_id: HirId::INVALID,
def_id: LocalDefId { local_def_index: DefIndex::ZERO },
body: BodyId { hir_id: HirId::INVALID },
span: DUMMY_SP,
}),
span: DUMMY_SP,
})}
},
}

cast_anon ConstArgKind Anon {
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1068,8 +1068,8 @@ pub fn walk_unambig_const_arg<'v, V: Visitor<'v>>(
match const_arg.try_as_ambig_ct() {
Some(ambig_ct) => visitor.visit_const_arg(ambig_ct),
None => {
let ConstArg { hir_id, kind: _ } = const_arg;
visitor.visit_infer(*hir_id, const_arg.span(), InferKind::Const(const_arg))
let ConstArg { hir_id, kind: _, span } = const_arg;
visitor.visit_infer(*hir_id, *span, InferKind::Const(const_arg))
}
}
}
Expand All @@ -1078,9 +1078,13 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
visitor: &mut V,
const_arg: &'v ConstArg<'v, AmbigArg>,
) -> V::Result {
let ConstArg { hir_id, kind } = const_arg;
let ConstArg { hir_id, kind, span: _ } = const_arg;
try_visit!(visitor.visit_id(*hir_id));
match kind {
ConstArgKind::Tup(exprs) => {
walk_list!(visitor, visit_const_arg, *exprs);
V::Result::output()
}
ConstArgKind::Struct(qpath, field_exprs) => {
try_visit!(visitor.visit_qpath(qpath, *hir_id, qpath.span()));

Expand All @@ -1099,7 +1103,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
}
ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()),
ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon),
ConstArgKind::Error(_, _) => V::Result::output(), // errors and spans are not important
ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important
}
}

Expand Down
18 changes: 11 additions & 7 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1479,23 +1479,27 @@ fn rendered_precise_capturing_args<'tcx>(

fn const_param_default<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
local_def_id: LocalDefId,
) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
let hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Const { default: Some(default_ct), .. },
..
}) = tcx.hir_node_by_def_id(def_id)
}) = tcx.hir_node_by_def_id(local_def_id)
else {
span_bug!(
tcx.def_span(def_id),
tcx.def_span(local_def_id),
"`const_param_default` expected a generic parameter with a constant"
)
};
let icx = ItemCtxt::new(tcx, def_id);
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);

let icx = ItemCtxt::new(tcx, local_def_id);

let def_id = local_def_id.to_def_id();
let identity_args = ty::GenericArgs::identity_for_item(tcx, tcx.parent(def_id));

let ct = icx
.lowerer()
.lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id(), identity_args));
.lower_const_arg(default_ct, FeedConstTy::with_type_of(tcx, def_id, identity_args));
ty::EarlyBinder::bind(ct)
}

Expand Down Expand Up @@ -1553,7 +1557,7 @@ fn const_of_item<'tcx>(
let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
let ct = icx
.lowerer()
.lower_const_arg(ct_arg, FeedConstTy::Param(def_id.to_def_id(), identity_args));
.lower_const_arg(ct_arg, FeedConstTy::with_type_of(tcx, def_id.to_def_id(), identity_args));
if let Err(e) = icx.check_tainted_by_errors()
&& !ct.references_error()
{
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
{
let span = match term {
hir::Term::Ty(ty) => ty.span,
hir::Term::Const(ct) => ct.span(),
hir::Term::Const(ct) => ct.span,
};
(span, Some(ident.span), assoc_item.as_tag(), assoc_tag)
} else {
Expand Down Expand Up @@ -1466,7 +1466,7 @@ pub fn prohibit_assoc_item_constraint(
hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(c) },
GenericParamDefKind::Const { .. },
) => {
suggest_direct_use(&mut err, c.span());
suggest_direct_use(&mut err, c.span);
}
(hir::AssocItemConstraintKind::Bound { bounds }, _) => {
// Suggest `impl<T: Bound> Trait<T> for Foo` when finding
Expand Down
Loading
Loading