From 252fa782836785d947ec67ef915553b30b32ce68 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 19 Mar 2023 19:06:14 +0000 Subject: [PATCH 1/2] Only expect a GAT const arg --- .../rustc_hir_analysis/src/collect/type_of.rs | 15 ++++++++++----- .../mismatched-gat-subst-kind.rs | 11 +++++++++++ .../mismatched-gat-subst-kind.stderr | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index fe44fabf57df9..a8e59715b7529 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -475,7 +475,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> def_id.to_def_id(), ); if let Some(assoc_item) = assoc_item { - tcx.type_of(assoc_item.def_id).subst_identity() + tcx.type_of(assoc_item.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic") } else { // FIXME(associated_const_equality): add a useful error message here. tcx.ty_error_with_message( @@ -517,15 +519,18 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> }, def_id.to_def_id(), ); - if let Some(param) - = assoc_item.map(|item| &tcx.generics_of(item.def_id).params[idx]).filter(|param| param.kind.is_ty_or_const()) + if let Some(assoc_item) = assoc_item + && let param = &tcx.generics_of(assoc_item.def_id).params[idx] + && matches!(param.kind, ty::GenericParamDefKind::Const { .. }) { - tcx.type_of(param.def_id).subst_identity() + tcx.type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic") } else { // FIXME(associated_const_equality): add a useful error message here. tcx.ty_error_with_message( DUMMY_SP, - "Could not find associated const on trait", + "Could not find const param on associated item", ) } } diff --git a/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs new file mode 100644 index 0000000000000..734a37862940f --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.rs @@ -0,0 +1,11 @@ +#![feature(generic_const_exprs)] +//~^ WARN the feature `generic_const_exprs` is incomplete + +trait B { + type U; +} + +fn f = ()>>() {} +//~^ ERROR constant provided when a type was expected + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr new file mode 100644 index 0000000000000..8b6eb5b75940f --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/mismatched-gat-subst-kind.stderr @@ -0,0 +1,18 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/mismatched-gat-subst-kind.rs:1:12 + | +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0747]: constant provided when a type was expected + --> $DIR/mismatched-gat-subst-kind.rs:8:13 + | +LL | fn f = ()>>() {} + | ^^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0747`. From dbedf4003f6b8402f42cd079fa82b046a32d2845 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 19 Mar 2023 23:44:37 +0000 Subject: [PATCH 2/2] Reformat type_of --- .../rustc_hir_analysis/src/collect/type_of.rs | 53 +++++++++++-------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index a8e59715b7529..4bbea87890429 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -278,8 +278,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> } TraitItemKind::Const(ty, body_id) => body_id .and_then(|body_id| { - is_suggestable_infer_ty(ty) - .then(|| infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant",)) + is_suggestable_infer_ty(ty).then(|| { + infer_placeholder_type( + tcx, def_id, body_id, ty.span, item.ident, "constant", + ) + }) }) .unwrap_or_else(|| icx.to_ty(ty)), TraitItemKind::Type(_, Some(ty)) => icx.to_ty(ty), @@ -335,14 +338,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> } } ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty), - ItemKind::Impl(hir::Impl { self_ty, .. }) => { - match self_ty.find_self_aliases() { - spans if spans.len() > 0 => { - let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () }); - tcx.ty_error(guar) - }, - _ => icx.to_ty(*self_ty), + ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() { + spans if spans.len() > 0 => { + let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf { + span: spans.into(), + note: (), + }); + tcx.ty_error(guar) } + _ => icx.to_ty(*self_ty), }, ItemKind::Fn(..) => { let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); @@ -364,7 +368,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> .. }) => { if in_trait && !tcx.impl_defaultness(owner).has_value() { - span_bug!(tcx.def_span(def_id), "tried to get type of this RPITIT with no definition"); + span_bug!( + tcx.def_span(def_id), + "tried to get type of this RPITIT with no definition" + ); } find_opaque_ty_constraints_for_rpit(tcx, def_id, owner) } @@ -453,15 +460,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) } - Node::TypeBinding( - TypeBinding { - hir_id: binding_id, - kind: TypeBindingKind::Equality { term: Term::Const(e) }, - ident, - .. - }, - ) if let Node::TraitRef(trait_ref) = - tcx.hir().get_parent(*binding_id) + Node::TypeBinding(TypeBinding { + hir_id: binding_id, + kind: TypeBindingKind::Equality { term: Term::Const(e) }, + ident, + .. + }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id) && e.hir_id == hir_id => { let Some(trait_def_id) = trait_ref.trait_def_id() else { @@ -487,10 +491,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder> } } - Node::TypeBinding( - TypeBinding { hir_id: binding_id, gen_args, kind, ident, .. }, - ) if let Node::TraitRef(trait_ref) = - tcx.hir().get_parent(*binding_id) + Node::TypeBinding(TypeBinding { + hir_id: binding_id, + gen_args, + kind, + ident, + .. + }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id) && let Some((idx, _)) = gen_args.args.iter().enumerate().find(|(_, arg)| { if let GenericArg::Const(ct) = arg {