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: 0 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3789,7 +3789,6 @@ dependencies = [
"rustc_mir_build",
"rustc_mir_transform",
"rustc_parse",
"rustc_passes",
"rustc_public",
"rustc_resolve",
"rustc_session",
Expand Down Expand Up @@ -4417,7 +4416,6 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2570,7 +2570,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

ConstArg {
hir_id: self.lower_node_id(expr.id),
kind: hir::ConstArgKind::Literal(literal.node),
kind: hir::ConstArgKind::Literal { lit: literal.node, negated: false },
span,
}
}
ExprKind::Unary(UnOp::Neg, inner_expr)
if let ExprKind::Lit(literal) = &inner_expr.kind =>
{
let span = expr.span;
let literal = self.lower_lit(literal, span);

ConstArg {
hir_id: self.lower_node_id(expr.id),
kind: hir::ConstArgKind::Literal { lit: literal.node, negated: true },
span,
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_driver_impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ rustc_middle = { path = "../rustc_middle" }
rustc_mir_build = { path = "../rustc_mir_build" }
rustc_mir_transform = { path = "../rustc_mir_transform" }
rustc_parse = { path = "../rustc_parse" }
rustc_passes = { path = "../rustc_passes" }
rustc_public = { path = "../rustc_public", features = ["rustc_internal"] }
rustc_resolve = { path = "../rustc_resolve" }
rustc_session = { path = "../rustc_session" }
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
rustc_lint::DEFAULT_LOCALE_RESOURCE,
rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
rustc_parse::DEFAULT_LOCALE_RESOURCE,
rustc_passes::DEFAULT_LOCALE_RESOURCE,
// tidy-alphabetical-end
];

Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,10 @@ pub enum ConstArgKind<'hir, Unambig = ()> {
/// This variant is not always used to represent inference consts, sometimes
/// [`GenericArg::Infer`] is used instead.
Infer(Unambig),
Literal(LitKind),
Literal {
lit: LitKind,
negated: bool,
},
}

#[derive(Clone, Copy, Debug, HashStable_Generic)]
Expand Down Expand Up @@ -1958,8 +1961,6 @@ pub struct PatExpr<'hir> {
pub enum PatExprKind<'hir> {
Lit {
lit: Lit,
// FIXME: move this into `Lit` and handle negated literal expressions
// once instead of matching on unop neg expressions everywhere.
negated: bool,
},
/// A path pattern for a unit struct/variant or a (maybe-associated) constant.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1110,7 +1110,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::Literal(..) => V::Result::output(), // FIXME(mcga)
ConstArgKind::Literal { .. } => V::Result::output(), // FIXME(mcga)
}
}

Expand Down
79 changes: 49 additions & 30 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1422,14 +1422,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
LowerTypeRelativePathMode::Const,
)? {
TypeRelativePath::AssocItem(def_id, args) => {
if !self.tcx().is_type_const(def_id) {
let mut err = self.dcx().struct_span_err(
span,
"use of trait associated const without `#[type_const]`",
);
err.note("the declaration in the trait must be marked with `#[type_const]`");
return Err(err.emit());
}
self.require_type_const_attribute(def_id, span)?;
let ct = Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args));
let ct = self.check_param_uses_if_mcg(ct, span, false);
Ok(ct)
Expand Down Expand Up @@ -1885,30 +1878,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
item_def_id: DefId,
trait_segment: Option<&hir::PathSegment<'tcx>>,
item_segment: &hir::PathSegment<'tcx>,
) -> Const<'tcx> {
match self.lower_resolved_assoc_item_path(
) -> Result<Const<'tcx>, ErrorGuaranteed> {
let (item_def_id, item_args) = self.lower_resolved_assoc_item_path(
span,
opt_self_ty,
item_def_id,
trait_segment,
item_segment,
ty::AssocTag::Const,
) {
Ok((item_def_id, item_args)) => {
if !self.tcx().is_type_const(item_def_id) {
let mut err = self.dcx().struct_span_err(
span,
"use of `const` in the type system without `#[type_const]`",
);
err.note("the declaration must be marked with `#[type_const]`");
return Const::new_error(self.tcx(), err.emit());
}

let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
Const::new_unevaluated(self.tcx(), uv)
}
Err(guar) => Const::new_error(self.tcx(), guar),
}
)?;
self.require_type_const_attribute(item_def_id, span)?;
let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
Ok(Const::new_unevaluated(self.tcx(), uv))
}

/// Lower a [resolved][hir::QPath::Resolved] (type-level) associated item path.
Expand Down Expand Up @@ -2396,8 +2377,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon),
hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span),
hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e),
hir::ConstArgKind::Literal(kind) => {
self.lower_const_arg_literal(&kind, ty, const_arg.span)
hir::ConstArgKind::Literal { lit, negated } => {
self.lower_const_arg_literal(&lit, negated, ty, const_arg.span)
}
}
}
Expand Down Expand Up @@ -2668,6 +2649,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self.lower_const_param(def_id, hir_id)
}
Res::Def(DefKind::Const, did) => {
if let Err(guar) = self.require_type_const_attribute(did, span) {
return Const::new_error(self.tcx(), guar);
}

assert_eq!(opt_self_ty, None);
let [leading_segments @ .., segment] = path.segments else { bug!() };
let _ = self
Expand Down Expand Up @@ -2718,6 +2703,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
trait_segment,
path.segments.last().unwrap(),
)
.unwrap_or_else(|guar| Const::new_error(tcx, guar))
}
Res::Def(DefKind::Static { .. }, _) => {
span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
Expand Down Expand Up @@ -2804,9 +2790,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}

#[instrument(skip(self), level = "debug")]
fn lower_const_arg_literal(&self, kind: &LitKind, ty: Ty<'tcx>, span: Span) -> Const<'tcx> {
fn lower_const_arg_literal(
&self,
kind: &LitKind,
neg: bool,
ty: Ty<'tcx>,
span: Span,
) -> Const<'tcx> {
let tcx = self.tcx();
let input = LitToConstInput { lit: *kind, ty, neg: false };
let input = LitToConstInput { lit: *kind, ty, neg };
tcx.at(span).lit_to_const(input)
}

Expand Down Expand Up @@ -2843,6 +2835,33 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.map(|l| tcx.at(expr.span).lit_to_const(l))
}

fn require_type_const_attribute(
&self,
def_id: DefId,
span: Span,
) -> Result<(), ErrorGuaranteed> {
let tcx = self.tcx();
if tcx.is_type_const(def_id) {
Ok(())
} else {
let mut err = self
.dcx()
.struct_span_err(span, "use of `const` in the type system without `#[type_const]`");
if def_id.is_local() {
let name = tcx.def_path_str(def_id);
err.span_suggestion(
tcx.def_span(def_id).shrink_to_lo(),
format!("add `#[type_const]` attribute to `{name}`"),
format!("#[type_const]\n"),
Applicability::MaybeIncorrect,
);
} else {
err.note("only consts marked with `#[type_const]` may be used in types");
}
Err(err.emit())
}
}

fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
match idx {
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1158,9 +1158,12 @@ impl<'a> State<'a> {
ConstArgKind::Anon(anon) => self.print_anon_const(anon),
ConstArgKind::Error(_) => self.word("/*ERROR*/"),
ConstArgKind::Infer(..) => self.word("_"),
ConstArgKind::Literal(node) => {
ConstArgKind::Literal { lit, negated } => {
if *negated {
self.word("-");
}
let span = const_arg.span;
self.print_literal(&Spanned { span, node: *node })
self.print_literal(&Spanned { span, node: *lit })
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
| hir::ConstArgKind::TupleCall(..)
| hir::ConstArgKind::Tup(..)
| hir::ConstArgKind::Path(..)
| hir::ConstArgKind::Literal(..)
| hir::ConstArgKind::Literal { .. }
| hir::ConstArgKind::Infer(..) => true,
hir::ConstArgKind::Anon(..) => false,
},
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_passes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_expand = { path = "../rustc_expand" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
Expand Down
Loading
Loading