From bbc536d3ac83ad0e3600af2d04701faed63ecd79 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 1 May 2023 05:15:45 +0000 Subject: [PATCH 1/2] Emit an error when RTN is used with ty/ct params --- compiler/rustc_hir_analysis/messages.ftl | 7 +++++ .../rustc_hir_analysis/src/astconv/mod.rs | 26 +++++++++++++++-- compiler/rustc_hir_analysis/src/errors.rs | 18 ++++++++++++ .../return-type-notation/ty-or-ct-params.rs | 20 +++++++++++++ .../ty-or-ct-params.stderr | 29 +++++++++++++++++++ 5 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 tests/ui/async-await/return-type-notation/ty-or-ct-params.rs create mode 100644 tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 02d1dfcd113..cd6cf36baa4 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -195,6 +195,13 @@ hir_analysis_return_type_notation_conflicting_bound = hir_analysis_return_type_notation_equality_bound = return type notation is not allowed to use type equality +hir_analysis_return_type_notation_illegal_param_const = + return type notation is not allowed for functions that have const parameters + .label = const parameter declared here +hir_analysis_return_type_notation_illegal_param_type = + return type notation is not allowed for functions that have type parameters + .label = type parameter declared here + hir_analysis_return_type_notation_missing_method = cannot find associated function `{$assoc_name}` for `{$ty_name}` diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 3d78ea9aa9b..37f17657961 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1215,6 +1215,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } let projection_ty = if return_type_notation { + let mut emitted_bad_param_err = false; // If we have an method return type bound, then we need to substitute // the method's early bound params with suitable late-bound params. let mut num_bound_vars = candidate.bound_vars().len(); @@ -1230,16 +1231,35 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }, ) .into(), - GenericParamDefKind::Type { .. } => tcx - .mk_bound( + GenericParamDefKind::Type { .. } => { + if !emitted_bad_param_err { + tcx.sess.emit_err( + crate::errors::ReturnTypeNotationIllegalParam::Type { + span: path_span, + param_span: tcx.def_span(param.def_id), + }, + ); + emitted_bad_param_err = true; + } + tcx.mk_bound( ty::INNERMOST, ty::BoundTy { var: ty::BoundVar::from_usize(num_bound_vars), kind: ty::BoundTyKind::Param(param.def_id, param.name), }, ) - .into(), + .into() + } GenericParamDefKind::Const { .. } => { + if !emitted_bad_param_err { + tcx.sess.emit_err( + crate::errors::ReturnTypeNotationIllegalParam::Const { + span: path_span, + param_span: tcx.def_span(param.def_id), + }, + ); + emitted_bad_param_err = true; + } let ty = tcx .type_of(param.def_id) .no_bound_vars() diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 6e7eb4f6cdc..7dce1272f96 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -857,3 +857,21 @@ pub(crate) enum DropImplPolarity { span: Span, }, } + +#[derive(Diagnostic)] +pub(crate) enum ReturnTypeNotationIllegalParam { + #[diag(hir_analysis_return_type_notation_illegal_param_type)] + Type { + #[primary_span] + span: Span, + #[label] + param_span: Span, + }, + #[diag(hir_analysis_return_type_notation_illegal_param_const)] + Const { + #[primary_span] + span: Span, + #[label] + param_span: Span, + }, +} diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs b/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs new file mode 100644 index 00000000000..7871a2fed03 --- /dev/null +++ b/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs @@ -0,0 +1,20 @@ +// edition: 2021 + +#![feature(async_fn_in_trait, return_type_notation)] +//~^ WARN the feature `return_type_notation` is incomplete + +trait Foo { + async fn bar() {} + + async fn baz() {} +} + +fn test() +where + T: Foo, + //~^ ERROR return type notation is not allowed for functions that have const parameters + //~| ERROR return type notation is not allowed for functions that have type parameters +{ +} + +fn main() {} diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr b/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr new file mode 100644 index 00000000000..76928c5d7a3 --- /dev/null +++ b/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr @@ -0,0 +1,29 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/ty-or-ct-params.rs:3:31 + | +LL | #![feature(async_fn_in_trait, return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: return type notation is not allowed for functions that have type parameters + --> $DIR/ty-or-ct-params.rs:14:12 + | +LL | async fn bar() {} + | - type parameter declared here +... +LL | T: Foo, + | ^^^^^^^^^^^ + +error: return type notation is not allowed for functions that have const parameters + --> $DIR/ty-or-ct-params.rs:14:25 + | +LL | async fn baz() {} + | -------------- const parameter declared here +... +LL | T: Foo, + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + From b0eaaca31457672a8022312cc0f89b18ebc9d754 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 5 Jun 2023 20:05:08 +0000 Subject: [PATCH 2/2] Remove redundant InferCtxtExt::fresh_item_substs --- .../rustc_hir_analysis/src/astconv/mod.rs | 37 +------------------ compiler/rustc_hir_typeck/src/method/probe.rs | 5 +-- .../rustc_infer/src/infer/type_variable.rs | 1 - compiler/rustc_middle/src/infer/unify_key.rs | 1 - 4 files changed, 3 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 37f17657961..8d3c0a4fb9e 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -26,10 +26,8 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{walk_generics, Visitor as _}; use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; @@ -2488,7 +2486,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { infcx.probe(|_| { let ocx = ObligationCtxt::new_in_snapshot(&infcx); - let impl_substs = infcx.fresh_item_substs(impl_); + let impl_substs = infcx.fresh_substs_for_item(span, impl_); let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs); let impl_ty = ocx.normalize(&cause, param_env, impl_ty); @@ -3775,36 +3773,3 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } } - -pub trait InferCtxtExt<'tcx> { - fn fresh_item_substs(&self, def_id: DefId) -> SubstsRef<'tcx>; -} - -impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { - fn fresh_item_substs(&self, def_id: DefId) -> SubstsRef<'tcx> { - InternalSubsts::for_item(self.tcx, def_id, |param, _| match param.kind { - GenericParamDefKind::Lifetime => self.tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } => self - .next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::SubstitutionPlaceholder, - span: self.tcx.def_span(def_id), - }) - .into(), - GenericParamDefKind::Const { .. } => { - let span = self.tcx.def_span(def_id); - let origin = ConstVariableOrigin { - kind: ConstVariableOriginKind::SubstitutionPlaceholder, - span, - }; - self.next_const_var( - self.tcx - .type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"), - origin, - ) - .into() - } - }) - } -} diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 9f3d35a77dc..b7b11ff8942 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -9,7 +9,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir_analysis::astconv::InferCtxtExt as _; use rustc_hir_analysis::autoderef::{self, Autoderef}; use rustc_infer::infer::canonical::OriginalQueryValues; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; @@ -954,7 +953,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { trait_def_id: DefId, ) { debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id); - let trait_substs = self.fresh_item_substs(trait_def_id); + let trait_substs = self.fresh_substs_for_item(self.span, trait_def_id); let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, trait_substs); if self.tcx.is_trait_alias(trait_def_id) { @@ -1899,7 +1898,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { &self, impl_def_id: DefId, ) -> (ty::EarlyBinder>, SubstsRef<'tcx>) { - (self.tcx.type_of(impl_def_id), self.fresh_item_substs(impl_def_id)) + (self.tcx.type_of(impl_def_id), self.fresh_substs_for_item(self.span, impl_def_id)) } /// Replaces late-bound-regions bound by `value` with `'static` using diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index f7ab05b2d49..9f85f9207e8 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -129,7 +129,6 @@ pub enum TypeVariableOriginKind { /// (before it has been determined). // FIXME(eddyb) distinguish upvar inference variables from the rest. ClosureSynthetic, - SubstitutionPlaceholder, AutoDeref, AdjustmentType, diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index a873854f068..991b9f01985 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -116,7 +116,6 @@ pub enum ConstVariableOriginKind { MiscVariable, ConstInference, ConstParameterDefinition(Symbol, DefId), - SubstitutionPlaceholder, } #[derive(Copy, Clone, Debug)]