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...
This commit is contained in:
commit
e94bda3bf1
8 changed files with 100 additions and 44 deletions
|
@ -195,6 +195,13 @@ hir_analysis_return_type_notation_conflicting_bound =
|
||||||
hir_analysis_return_type_notation_equality_bound =
|
hir_analysis_return_type_notation_equality_bound =
|
||||||
return type notation is not allowed to use type equality
|
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 =
|
hir_analysis_return_type_notation_missing_method =
|
||||||
cannot find associated function `{$assoc_name}` for `{$ty_name}`
|
cannot find associated function `{$assoc_name}` for `{$ty_name}`
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,8 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::intravisit::{walk_generics, Visitor as _};
|
use rustc_hir::intravisit::{walk_generics, Visitor as _};
|
||||||
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
|
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
|
||||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
|
||||||
use rustc_middle::middle::stability::AllowUnstable;
|
use rustc_middle::middle::stability::AllowUnstable;
|
||||||
use rustc_middle::ty::fold::FnMutDelegate;
|
use rustc_middle::ty::fold::FnMutDelegate;
|
||||||
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
|
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 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
|
// If we have an method return type bound, then we need to substitute
|
||||||
// the method's early bound params with suitable late-bound params.
|
// the method's early bound params with suitable late-bound params.
|
||||||
let mut num_bound_vars = candidate.bound_vars().len();
|
let mut num_bound_vars = candidate.bound_vars().len();
|
||||||
|
@ -1230,16 +1229,35 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
GenericParamDefKind::Type { .. } => tcx
|
GenericParamDefKind::Type { .. } => {
|
||||||
.mk_bound(
|
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::INNERMOST,
|
||||||
ty::BoundTy {
|
ty::BoundTy {
|
||||||
var: ty::BoundVar::from_usize(num_bound_vars),
|
var: ty::BoundVar::from_usize(num_bound_vars),
|
||||||
kind: ty::BoundTyKind::Param(param.def_id, param.name),
|
kind: ty::BoundTyKind::Param(param.def_id, param.name),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.into(),
|
.into()
|
||||||
|
}
|
||||||
GenericParamDefKind::Const { .. } => {
|
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
|
let ty = tcx
|
||||||
.type_of(param.def_id)
|
.type_of(param.def_id)
|
||||||
.no_bound_vars()
|
.no_bound_vars()
|
||||||
|
@ -2472,7 +2490,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
infcx.probe(|_| {
|
infcx.probe(|_| {
|
||||||
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
|
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 = tcx.type_of(impl_).subst(tcx, impl_substs);
|
||||||
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
|
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()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -857,3 +857,21 @@ pub(crate) enum DropImplPolarity {
|
||||||
span: Span,
|
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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir_analysis::astconv::InferCtxtExt as _;
|
|
||||||
use rustc_hir_analysis::autoderef::{self, Autoderef};
|
use rustc_hir_analysis::autoderef::{self, Autoderef};
|
||||||
use rustc_infer::infer::canonical::OriginalQueryValues;
|
use rustc_infer::infer::canonical::OriginalQueryValues;
|
||||||
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
||||||
|
@ -954,7 +953,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
) {
|
) {
|
||||||
debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id);
|
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);
|
let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, trait_substs);
|
||||||
|
|
||||||
if self.tcx.is_trait_alias(trait_def_id) {
|
if self.tcx.is_trait_alias(trait_def_id) {
|
||||||
|
@ -1899,7 +1898,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
impl_def_id: DefId,
|
impl_def_id: DefId,
|
||||||
) -> (ty::EarlyBinder<Ty<'tcx>>, SubstsRef<'tcx>) {
|
) -> (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
|
/// Replaces late-bound-regions bound by `value` with `'static` using
|
||||||
|
|
|
@ -129,7 +129,6 @@ pub enum TypeVariableOriginKind {
|
||||||
/// (before it has been determined).
|
/// (before it has been determined).
|
||||||
// FIXME(eddyb) distinguish upvar inference variables from the rest.
|
// FIXME(eddyb) distinguish upvar inference variables from the rest.
|
||||||
ClosureSynthetic,
|
ClosureSynthetic,
|
||||||
SubstitutionPlaceholder,
|
|
||||||
AutoDeref,
|
AutoDeref,
|
||||||
AdjustmentType,
|
AdjustmentType,
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,6 @@ pub enum ConstVariableOriginKind {
|
||||||
MiscVariable,
|
MiscVariable,
|
||||||
ConstInference,
|
ConstInference,
|
||||||
ConstParameterDefinition(Symbol, DefId),
|
ConstParameterDefinition(Symbol, DefId),
|
||||||
SubstitutionPlaceholder,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|
20
tests/ui/async-await/return-type-notation/ty-or-ct-params.rs
Normal file
20
tests/ui/async-await/return-type-notation/ty-or-ct-params.rs
Normal file
|
@ -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() {}
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue