Skip to content

Commit

Permalink
Begin to use ConstArgKind::Path for all paths, not just params
Browse files Browse the repository at this point in the history
The test error changes are undesired and need to be investigated.
  • Loading branch information
camelid committed Oct 21, 2024
1 parent 3c1ec62 commit e3366ad
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 132 deletions.
57 changes: 10 additions & 47 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2298,56 +2298,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ty_id: NodeId,
span: Span,
) -> &'hir hir::ConstArg<'hir> {
let ct_kind = match res {
Res::Def(DefKind::ConstParam, _) => {
let qpath = self.lower_qpath(
ty_id,
&None,
path,
ParamMode::Optional,
AllowReturnTypeNotation::No,
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
hir::ConstArgKind::Path(qpath)
}
_ => {
// Construct an AnonConst where the expr is the "ty"'s path.

let parent_def_id = self.current_def_id_parent;
let node_id = self.next_node_id();
let span = self.lower_span(span);

// Add a definition for the in-band const def.
let def_id =
self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span);
let hir_id = self.lower_node_id(node_id);

let path_expr = Expr {
id: ty_id,
kind: ExprKind::Path(None, path.clone()),
span,
attrs: AttrVec::new(),
tokens: None,
};

let ct = self.with_new_scopes(span, |this| {
self.arena.alloc(hir::AnonConst {
def_id,
hir_id,
body: this.with_def_id_parent(def_id, |this| {
this.lower_const_body(path_expr.span, Some(&path_expr))
}),
span,
})
});
hir::ConstArgKind::Anon(ct)
}
};
let qpath = self.lower_qpath(
ty_id,
&None,
path,
ParamMode::Optional,
AllowReturnTypeNotation::No,
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);

self.arena.alloc(hir::ConstArg {
hir_id: self.next_id(),
kind: ct_kind,
kind: hir::ConstArgKind::Path(qpath),
is_desugared_from_effects: false,
})
}
Expand Down
15 changes: 5 additions & 10 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,12 @@ fn generic_arg_mismatch_err(
}
}
(GenericArg::Const(cnst), GenericParamDefKind::Type { .. }) => {
// FIXME(min_generic_const_args): once ConstArgKind::Path is used for non-params too,
// this should match against that instead of ::Anon
if let hir::ConstArgKind::Anon(anon) = cnst.kind
&& let body = tcx.hir().body(anon.body)
&& let rustc_hir::ExprKind::Path(rustc_hir::QPath::Resolved(_, path)) =
body.value.kind
if let hir::ConstArgKind::Path(qpath) = cnst.kind
&& let rustc_hir::QPath::Resolved(_, path) = qpath
&& let Res::Def(DefKind::Fn { .. }, id) = path.res
{
if let Res::Def(DefKind::Fn { .. }, id) = path.res {
err.help(format!("`{}` is a function item, not a type", tcx.item_name(id)));
err.help("function item types cannot be named directly");
}
err.help(format!("`{}` is a function item, not a type", tcx.item_name(id)));
err.help("function item types cannot be named directly");
}
}
_ => {}
Expand Down
57 changes: 39 additions & 18 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2010,41 +2010,62 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}

match const_arg.kind {
hir::ConstArgKind::Path(qpath) => {
// FIXME(min_generic_const_args): for now only params are lowered to ConstArgKind::Path
self.lower_const_arg_param(qpath, const_arg.hir_id)
}
hir::ConstArgKind::Path(qpath) => self.lower_const_arg_path(qpath, const_arg.hir_id),
hir::ConstArgKind::Anon(anon) => Const::from_anon_const(tcx, anon.def_id),
}
}

/// Lower a use of a const param to a [`Const`].
///
/// IMPORTANT: `qpath` must be a const param, otherwise this will panic
fn lower_const_arg_param(&self, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Const<'tcx> {
/// Lower a const path to a [`Const`].
fn lower_const_arg_path(&self, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Const<'tcx> {
let tcx = self.tcx();

let hir::QPath::Resolved(_, &hir::Path { res: Res::Def(DefKind::ConstParam, def_id), .. }) =
qpath
else {
span_bug!(qpath.span(), "non-param {qpath:?} passed to Const::from_param")
};
// TODO: handle path args properly
match qpath {
hir::QPath::Resolved(_, &hir::Path { res: Res::Def(DefKind::ConstParam, did), .. }) => {
self.lower_const_arg_param(did, hir_id)
}
hir::QPath::Resolved(
_,
&hir::Path { res: Res::Def(DefKind::Fn | DefKind::AssocFn, _), .. },
) => ty::Const::new_error_with_message(
tcx,
qpath.span(),
"fn's cannot be used as const args",
),
hir::QPath::Resolved(_, path @ &hir::Path { res: Res::Def(_, did), .. }) => {
let (item_segment, _) = path.segments.split_last().unwrap();
let args = self.lower_generic_args_of_path_segment(path.span, did, item_segment);
ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
}
// TODO: type-relative paths
_ => ty::Const::new_error_with_message(
tcx,
qpath.span(),
"Const::lower_const_arg_path: invalid qpath",
),
}
}

match tcx.named_bound_var(hir_id) {
/// Lower a const param to a [`Const`]. This is only meant as a helper for [`Self::lower_const_arg_path`].
/// FIXME: dedup with lower_const_param
fn lower_const_arg_param(&self, param_def_id: DefId, path_hir_id: HirId) -> Const<'tcx> {
let tcx = self.tcx();

match tcx.named_bound_var(path_hir_id) {
Some(rbv::ResolvedArg::EarlyBound(_)) => {
// Find the name and index of the const parameter by indexing the generics of
// the parent item and construct a `ParamConst`.
let item_def_id = tcx.parent(def_id);
let item_def_id = tcx.parent(param_def_id);
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id];
let name = tcx.item_name(def_id);
let index = generics.param_def_id_to_index[&param_def_id];
let name = tcx.item_name(param_def_id);
ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
}
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
}
Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", hir_id),
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,7 @@ LL | let _ = Checked::<{ generic_arg::<u32> }>;
= note: expected fn pointer `fn(usize) -> _`
found fn item `fn(u32) -> _ {generic_arg::<u32>}`

error[E0282]: type annotations needed
--> $DIR/fn-const-param-infer.rs:35:23
|
LL | let _ = Checked::<generic>;
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
|
help: consider specifying the generic argument
|
LL | let _ = Checked::<generic::<T>>;
| +++++

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0282, E0308, E0741.
For more information about an error, try `rustc --explain E0282`.
Some errors have detailed explanations: E0308, E0741.
For more information about an error, try `rustc --explain E0308`.
17 changes: 3 additions & 14 deletions tests/ui/const-generics/fn-const-param-infer.full.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,7 @@ LL | let _ = Checked::<{ generic_arg::<u32> }>;
= note: expected fn pointer `fn(usize) -> _`
found fn item `fn(u32) -> _ {generic_arg::<u32>}`

error[E0282]: type annotations needed
--> $DIR/fn-const-param-infer.rs:35:23
|
LL | let _ = Checked::<generic>;
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
|
help: consider specifying the generic argument
|
LL | let _ = Checked::<generic::<T>>;
| +++++

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0282, E0308, E0741.
For more information about an error, try `rustc --explain E0282`.
Some errors have detailed explanations: E0308, E0741.
For more information about an error, try `rustc --explain E0308`.
16 changes: 2 additions & 14 deletions tests/ui/const-generics/fn-const-param-infer.min.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,6 @@ LL | let _ = Checked::<{ generic_arg::<u32> }>;
= note: expected fn pointer `fn(usize) -> _`
found fn item `fn(u32) -> _ {generic_arg::<u32>}`

error[E0282]: type annotations needed
--> $DIR/fn-const-param-infer.rs:35:23
|
LL | let _ = Checked::<generic>;
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
|
help: consider specifying the generic argument
|
LL | let _ = Checked::<generic::<T>>;
| +++++

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.
For more information about this error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,33 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
LL + #![feature(adt_const_params)]
|

<<<<<<< HEAD
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
--> $DIR/unevaluated-const-ice-119731.rs:28:37
|
LL | impl<const v10: usize> v17<v10, v2> {
| ^^
||||||| parent of 883a4baff18 (Begin to use `ConstArgKind::Path` for all paths, not just params)
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
--> $DIR/unevaluated-const-ice-119731.rs:27:37
=======
error: maximum number of nodes exceeded in constant v20::v2
--> $DIR/unevaluated-const-ice-119731.rs:11:5
>>>>>>> 883a4baff18 (Begin to use `ConstArgKind::Path` for all paths, not just params)
|
LL | const v2: v11 = [[256; v4]; v4];
| ^^^^^^^^^^^^^

<<<<<<< HEAD
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
--> $DIR/unevaluated-const-ice-119731.rs:28:37
|
LL | impl<const v10: usize> v17<v10, v2> {
| ^^
||||||| parent of 883a4baff18 (Begin to use `ConstArgKind::Path` for all paths, not just params)
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
--> $DIR/unevaluated-const-ice-119731.rs:27:37
=======
error: maximum number of nodes exceeded in constant v20::v2
--> $DIR/unevaluated-const-ice-119731.rs:11:5
>>>>>>> 883a4baff18 (Begin to use `ConstArgKind::Path` for all paths, not just params)
|
LL | const v2: v11 = [[256; v4]; v4];
| ^^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

Expand Down
53 changes: 44 additions & 9 deletions tests/ui/const-generics/opaque_types2.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
error[E0308]: mismatched types
--> $DIR/opaque_types2.rs:13:11
error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
--> $DIR/opaque_types2.rs:3:12
|
LL | type Foo = impl Sized;
| ---------- the found opaque type
...
LL | foo::<C>();
| ^ expected `u32`, found opaque type
| ^^^^^^^^^^
|
= note: expected type `u32`
found opaque type `Foo`
note: ...which requires computing type of opaque `Foo::{opaque#0}`...
--> $DIR/opaque_types2.rs:3:12
|
LL | type Foo = impl Sized;
| ^^^^^^^^^^
note: ...which requires type-checking `bar`...
--> $DIR/opaque_types2.rs:9:1
|
LL | / fn bar()
LL | | where
LL | | Foo:,
| |_________^
note: ...which requires evaluating type-level constant...
--> $DIR/opaque_types2.rs:7:1
|
LL | const C: Foo = 42;
| ^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `C`...
--> $DIR/opaque_types2.rs:7:1
|
LL | const C: Foo = 42;
| ^^^^^^^^^^^^
note: ...which requires caching mir of `C` for CTFE...
--> $DIR/opaque_types2.rs:7:1
|
LL | const C: Foo = 42;
| ^^^^^^^^^^^^
note: ...which requires elaborating drops for `C`...
--> $DIR/opaque_types2.rs:7:1
|
LL | const C: Foo = 42;
| ^^^^^^^^^^^^
= note: ...which requires normalizing `Foo`...
= note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
note: cycle used when checking that `Foo::{opaque#0}` is well-formed
--> $DIR/opaque_types2.rs:3:12
|
LL | type Foo = impl Sized;
| ^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.
For more information about this error, try `rustc --explain E0391`.

0 comments on commit e3366ad

Please sign in to comment.