Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
camelid committed Oct 21, 2024
1 parent 507ada1 commit 4494a71
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 67 deletions.
67 changes: 62 additions & 5 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err,
};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{GenericArg, GenericArgs, HirId};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
Expand Down Expand Up @@ -2032,12 +2032,31 @@ impl<'tcx> dyn HirTyLowerer<'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))
// 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",
// ),
hir::QPath::Resolved(maybe_qself, path) => {
debug!(?maybe_qself, ?path);
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
self.lower_const_path_resolved(opt_self_ty, path, hir_id)
}

// TODO: type-relative paths
// hir::QPath::TypeRelative(qself, segment) => {
// debug!(?qself, ?segment);
// let ty = self.lower_ty(qself);
// self.lower_assoc_path(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false)
// .map(|(ty, _, _)| ty)
// .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
// }
_ => ty::Const::new_error_with_message(
tcx,
qpath.span(),
Expand All @@ -2046,6 +2065,44 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}
}

fn lower_const_path_resolved(
&self,
opt_self_ty: Option<Ty<'tcx>>,
path: &hir::Path<'tcx>,
hir_id: HirId,
) -> Const<'tcx> {
let tcx = self.tcx();
let span = path.span;
match path.res {
Res::Def(DefKind::ConstParam, def_id) => {
assert_eq!(opt_self_ty, None);
let _ = self.prohibit_generic_args(
path.segments.iter(),
GenericsArgsErrExtend::Param(def_id),
);
self.lower_const_arg_param(def_id, hir_id)
}
Res::Def(DefKind::Const | DefKind::Ctor(_, CtorKind::Const), did) => {
assert_eq!(opt_self_ty, None);
let _ = self.prohibit_generic_args(
path.segments.split_last().unwrap().1.iter(),
GenericsArgsErrExtend::None,
);
let args = self.lower_generic_args_of_path_segment(
span,
did,
path.segments.last().unwrap(),
);
ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
}
// TODO: DefKind::AssocConst?
_ => Const::new_error(
tcx,
tcx.dcx().span_delayed_bug(span, "invalid Res for const path"),
),
}
}

/// 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> {
Expand Down
13 changes: 2 additions & 11 deletions tests/ui/associated-consts/issue-58022.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
--> $DIR/issue-58022.rs:4:25
|
LL | const SIZE: usize;
| ------------------ `Foo::SIZE` defined here
LL |
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
| ^^^^^^^^^ cannot refer to the associated constant of trait

error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-58022.rs:13:41
|
Expand All @@ -27,7 +18,7 @@ error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo
LL | Foo(Box::new(*slice))
| ^^^ not a function, tuple struct or tuple variant

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

Some errors have detailed explanations: E0277, E0423, E0790.
Some errors have detailed explanations: E0277, E0423.
For more information about an error, try `rustc --explain E0277`.
13 changes: 2 additions & 11 deletions tests/ui/associated-item/issue-48027.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,6 @@ LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait

error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
--> $DIR/issue-48027.rs:3:32
|
LL | const X: usize;
| --------------- `Bar::X` defined here
LL | fn return_n(&self) -> [u8; Bar::X];
| ^^^^^^ cannot refer to the associated constant of trait

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

Some errors have detailed explanations: E0038, E0790.
For more information about an error, try `rustc --explain E0038`.
For more information about this error, try `rustc --explain E0038`.
16 changes: 1 addition & 15 deletions tests/ui/const-generics/bad-subst-const-kind.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,5 @@ error: the constant `N` is not of type `usize`
LL | impl<const N: u64> Q for [u8; N] {
| ^^^^^^^ expected `usize`, found `u64`

error: the constant `13` is not of type `u64`
--> $DIR/bad-subst-const-kind.rs:13:24
|
LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] {
| ^^^^^^^^ expected `u64`, found `usize`
|
note: required for `[u8; 13]` to implement `Q`
--> $DIR/bad-subst-const-kind.rs:8:20
|
LL | impl<const N: u64> Q for [u8; N] {
| ------------ ^ ^^^^^^^
| |
| unsatisfied trait bound introduced here

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

21 changes: 9 additions & 12 deletions tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
error[E0275]: overflow evaluating the requirement `S<{ U }> well-formed`
--> $DIR/adt_wf_hang.rs:11:5
error[E0741]: `U` must implement `ConstParamTy` to be used as the type of a const generic parameter
--> $DIR/adt_wf_hang.rs:9:19
|
LL | S<{ U }>:;
| ^^^^^^^^
LL | struct S<const N: U>()
| ^
|
note: required by a bound in `S`
--> $DIR/adt_wf_hang.rs:11:5
help: add `#[derive(ConstParamTy)]` to the struct
|
LL + #[derive(ConstParamTy)]
LL | struct U;
|
LL | struct S<const N: U>()
| - required by a bound in this struct
LL | where
LL | S<{ U }>:;
| ^^^^^^^^ required by this bound in `S`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.
For more information about this error, try `rustc --explain E0741`.
15 changes: 2 additions & 13 deletions tests/ui/variance/variance-associated-consts.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
error: unconstrained generic constant
--> $DIR/variance-associated-consts.rs:14:12
|
LL | field: [u8; <T as Trait>::Const]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: try adding a `where` bound
|
LL | struct Foo<T: Trait> where [(); <T as Trait>::Const]: {
| ++++++++++++++++++++++++++++++++

error: [T: o]
error: [T: *]
--> $DIR/variance-associated-consts.rs:13:1
|
LL | struct Foo<T: Trait> {
| ^^^^^^^^^^^^^^^^^^^^

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

0 comments on commit 4494a71

Please sign in to comment.