about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-07 09:03:33 +0000
committerbors <bors@rust-lang.org>2023-06-07 09:03:33 +0000
commite94bda3bf13303671427363d1cd93ac5e089f090 (patch)
treeb0b579b1ded684f093c43e1d5215d67f1173051d
parent10b7e468f3cc263b8df8ff0212d0911ed5a3c090 (diff)
parentb0eaaca31457672a8022312cc0f89b18ebc9d754 (diff)
downloadrust-e94bda3bf13303671427363d1cd93ac5e089f090.tar.gz
rust-e94bda3bf13303671427363d1cd93ac5e089f090.zip
Auto merge of #111047 - compiler-errors:rtn-no-ty-ct-params, r=spastorino
Emit an error when return-type-notation is used with type/const params

These are not intended to be supported initially, even though the compiler supports them internally...
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl7
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs63
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs18
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs5
-rw-r--r--compiler/rustc_infer/src/infer/type_variable.rs1
-rw-r--r--compiler/rustc_middle/src/infer/unify_key.rs1
-rw-r--r--tests/ui/async-await/return-type-notation/ty-or-ct-params.rs20
-rw-r--r--tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr29
8 files changed, 100 insertions, 44 deletions
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 95517f01414..a9e8afe434e 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};
@@ -1215,6 +1213,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 +1229,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()
@@ -2472,7 +2490,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);
 
@@ -3759,36 +3777,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_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/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<Ty<'tcx>>, 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)]
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<T>() {}
+
+    async fn baz<const N: usize>() {}
+}
+
+fn test<T>()
+where
+    T: Foo<bar(): Send, baz(): Send>,
+    //~^ 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 <https://github.com/rust-lang/rust/issues/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<T>() {}
+   |                  - type parameter declared here
+...
+LL |     T: Foo<bar(): Send, baz(): Send>,
+   |            ^^^^^^^^^^^
+
+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 N: usize>() {}
+   |                  -------------- const parameter declared here
+...
+LL |     T: Foo<bar(): Send, baz(): Send>,
+   |                         ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
+