diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4d8d22e09d922..53306df3a59c1 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -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, }) } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 6e8a9ded4f370..05c1fb2c28905 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -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"); } } _ => {} diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index b02dc0d8b6377..020c0f968947a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -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[¶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), } } 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 30a45ce377e7e..8043cdeb6880a 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,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::::{constant#0} --> $DIR/unevaluated-const-ice-119731.rs:28:37 - | -LL | impl v17 { - | ^^ +||||||| parent of 883a4baff18 (Begin to use `ConstArgKind::Path` for all paths, not just 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 +>>>>>>> 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::::{constant#0} --> $DIR/unevaluated-const-ice-119731.rs:28:37 - | -LL | impl v17 { - | ^^ +||||||| parent of 883a4baff18 (Begin to use `ConstArgKind::Path` for all paths, not just 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 +>>>>>>> 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` 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`.