diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c6cb7aa7dd5c2..98970e55251f0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2357,53 +2357,16 @@ 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, + ); + let ct_kind = hir::ConstArgKind::Path(qpath); self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind: ct_kind, diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 73d0acf95f4f5..7ff8d50870bc2 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -215,10 +215,7 @@ impl<'tcx> Const<'tcx> { } match const_arg.kind { - hir::ConstArgKind::Path(qpath) => { - // FIXME(min_generic_const_args): for now only params are lowered to ConstArgKind::Path - Self::from_param(tcx, qpath, const_arg.hir_id) - } + hir::ConstArgKind::Path(qpath) => Self::from_path(tcx, qpath, const_arg.hir_id), hir::ConstArgKind::Anon(anon) => Self::from_anon_const(tcx, anon.def_id), } } @@ -240,7 +237,7 @@ impl<'tcx> Const<'tcx> { let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic"); - match Self::try_from_lit_or_param(tcx, ty, expr) { + match Self::try_from_lit(tcx, ty, expr) { Some(v) => v, None => ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst { def: def.to_def_id(), @@ -249,40 +246,54 @@ impl<'tcx> Const<'tcx> { } } - /// Lower a const param to a [`Const`]. - /// - /// IMPORTANT: `qpath` must be a const param, otherwise this will panic - fn from_param(tcx: TyCtxt<'tcx>, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Self { - 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") - }; + fn from_path(tcx: TyCtxt<'tcx>, qpath: hir::QPath<'tcx>, hir_id: HirId) -> Self { + match qpath { + hir::QPath::Resolved(_, &path) => match path.res { + Res::Def(DefKind::ConstParam, def_id) => Self::from_param(tcx, def_id, hir_id), + Res::Def(DefKind::Const, def_id) => { + // FIXME: support parametrized consts (instead of empty list). + let uv = ty::UnevaluatedConst::new(def_id, ty::List::empty()); + Self::new_unevaluated(tcx, uv) + } + r => Self::new_error( + tcx, + tcx.dcx().span_delayed_bug( + tcx.hir().span(hir_id), + format!("Const::from_path: invalid qpath res: {r:?}"), + ), + ), + }, + hir::QPath::TypeRelative(..) => todo!("associated const paths"), + // FIXME: use span_delayed_bug? + hir::QPath::LangItem(..) => span_bug!( + tcx.hir().span(hir_id), + "Const::from_path: invalid qpath provided: {qpath:?}" + ), + } + } - match tcx.named_bound_var(hir_id) { + /// Lower a const param to a [`Const`]. This is only meant as a helper for [`Self::from_path`]. + fn from_param(tcx: TyCtxt<'tcx>, param_def_id: DefId, path_hir_id: HirId) -> Self { + 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[¶m_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), } } #[instrument(skip(tcx), level = "debug")] - fn try_from_lit_or_param( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, - expr: &'tcx hir::Expr<'tcx>, - ) -> Option { + fn try_from_lit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) -> Option { // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments // currently have to be wrapped in curly brackets, so it's necessary to special-case. let expr = match &expr.kind { diff --git a/tests/ui/const-generics/fn-const-param-infer.adt_const_params.stderr b/tests/ui/const-generics/fn-const-param-infer.adt_const_params.stderr index 54f3bff172af6..f5978d6ebc361 100644 --- a/tests/ui/const-generics/fn-const-param-infer.adt_const_params.stderr +++ b/tests/ui/const-generics/fn-const-param-infer.adt_const_params.stderr @@ -13,18 +13,7 @@ LL | let _ = Checked::<{ generic_arg:: }>; = note: expected fn pointer `fn(usize) -> _` found fn item `fn(u32) -> _ {generic_arg::}` -error[E0282]: type annotations needed - --> $DIR/fn-const-param-infer.rs:35:23 - | -LL | let _ = Checked::; - | ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic` - | -help: consider specifying the generic argument - | -LL | let _ = Checked::>; - | +++++ - -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`. diff --git a/tests/ui/const-generics/fn-const-param-infer.full.stderr b/tests/ui/const-generics/fn-const-param-infer.full.stderr index 54f3bff172af6..f5978d6ebc361 100644 --- a/tests/ui/const-generics/fn-const-param-infer.full.stderr +++ b/tests/ui/const-generics/fn-const-param-infer.full.stderr @@ -13,18 +13,7 @@ LL | let _ = Checked::<{ generic_arg:: }>; = note: expected fn pointer `fn(usize) -> _` found fn item `fn(u32) -> _ {generic_arg::}` -error[E0282]: type annotations needed - --> $DIR/fn-const-param-infer.rs:35:23 - | -LL | let _ = Checked::; - | ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic` - | -help: consider specifying the generic argument - | -LL | let _ = Checked::>; - | +++++ - -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`. diff --git a/tests/ui/const-generics/fn-const-param-infer.min.stderr b/tests/ui/const-generics/fn-const-param-infer.min.stderr index 5e08f71a26701..f5da6af9383e4 100644 --- a/tests/ui/const-generics/fn-const-param-infer.min.stderr +++ b/tests/ui/const-generics/fn-const-param-infer.min.stderr @@ -15,18 +15,6 @@ LL | let _ = Checked::<{ generic_arg:: }>; = note: expected fn pointer `fn(usize) -> _` found fn item `fn(u32) -> _ {generic_arg::}` -error[E0282]: type annotations needed - --> $DIR/fn-const-param-infer.rs:35:23 - | -LL | let _ = Checked::; - | ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic` - | -help: consider specifying the generic argument - | -LL | let _ = Checked::>; - | +++++ - -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`. diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index 45be31c7ba35f..3d90a4434fdbc 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -72,17 +72,17 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more LL + #![feature(adt_const_params)] | -error: maximum number of nodes exceeded in constant v20::v17::::{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 | -LL | impl v17 { - | ^^ +LL | const v2: v11 = [[256; v4]; v4]; + | ^^^^^^^^^^^^^ -error: maximum number of nodes exceeded in constant v20::v17::::{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 | -LL | impl v17 { - | ^^ +LL | const v2: v11 = [[256; v4]; v4]; + | ^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/const-generics/opaque_types2.stderr b/tests/ui/const-generics/opaque_types2.stderr index 2fb1669b7bfab..a5696eb69610d 100644 --- a/tests/ui/const-generics/opaque_types2.stderr +++ b/tests/ui/const-generics/opaque_types2.stderr @@ -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::(); - | ^ 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`. diff --git a/tests/ui/generics/generic-function-item-where-type.stderr b/tests/ui/generics/generic-function-item-where-type.stderr index 00e62843cb4b6..5ba863bc2ef99 100644 --- a/tests/ui/generics/generic-function-item-where-type.stderr +++ b/tests/ui/generics/generic-function-item-where-type.stderr @@ -3,9 +3,6 @@ error[E0747]: constant provided when a type was expected | LL | foo::
() | ^^^^ - | - = help: `main` is a function item, not a type - = help: function item types cannot be named directly error: aborting due to 1 previous error