mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
Conditionally allow lowering RTN (..) in paths
This commit is contained in:
parent
6d788a18c5
commit
19881b5a5a
@ -20,8 +20,8 @@ use super::errors::{
|
||||
};
|
||||
use super::LoweringContext;
|
||||
use crate::{
|
||||
fluent_generated as fluent, ImplTraitContext, ImplTraitPosition, ParamMode,
|
||||
ResolverAstLoweringExt,
|
||||
fluent_generated as fluent, AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition,
|
||||
ParamMode, ResolverAstLoweringExt,
|
||||
};
|
||||
|
||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
@ -201,6 +201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
&sym.qself,
|
||||
&sym.path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
|
@ -52,7 +52,7 @@ use rustc_target::spec::abi;
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode};
|
||||
use crate::{ImplTraitPosition, ResolverAstLoweringExt};
|
||||
use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt};
|
||||
|
||||
pub(crate) struct DelegationResults<'hir> {
|
||||
pub body_id: hir::BodyId,
|
||||
@ -340,6 +340,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
&delegation.qself,
|
||||
&delegation.path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
|
@ -23,7 +23,7 @@ use super::{
|
||||
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
|
||||
};
|
||||
use crate::errors::YieldInClosure;
|
||||
use crate::{fluent_generated, FnDeclKind, ImplTraitPosition};
|
||||
use crate::{fluent_generated, AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition};
|
||||
|
||||
impl<'hir> LoweringContext<'_, 'hir> {
|
||||
fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
|
||||
@ -281,6 +281,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
qself,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
@ -328,6 +329,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
&se.qself,
|
||||
&se.path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
)),
|
||||
@ -1291,6 +1293,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
qself,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
@ -1311,6 +1314,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
qself,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
@ -1336,6 +1340,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
&se.qself,
|
||||
&se.path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
|
@ -485,8 +485,16 @@ enum ParamMode {
|
||||
Optional,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum AllowReturnTypeNotation {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum GenericArgsMode {
|
||||
ParenSugar,
|
||||
ReturnTypeNotation,
|
||||
Err,
|
||||
}
|
||||
|
||||
@ -1226,7 +1234,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
|
||||
let id = self.lower_node_id(t.id);
|
||||
let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, None);
|
||||
let qpath = self.lower_qpath(
|
||||
t.id,
|
||||
qself,
|
||||
path,
|
||||
param_mode,
|
||||
// We deny these after the fact in HIR->middle type lowering.
|
||||
AllowReturnTypeNotation::Yes,
|
||||
itctx,
|
||||
None,
|
||||
);
|
||||
self.ty_path(id, t.span, qpath)
|
||||
}
|
||||
|
||||
@ -2203,6 +2220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
&None,
|
||||
&p.path,
|
||||
ParamMode::Explicit,
|
||||
AllowReturnTypeNotation::No,
|
||||
itctx,
|
||||
Some(modifiers),
|
||||
) {
|
||||
@ -2341,6 +2359,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
&None,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
@ -2419,6 +2438,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
qself,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
|
@ -11,7 +11,7 @@ use super::errors::{
|
||||
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
||||
};
|
||||
use super::{ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt};
|
||||
use crate::ImplTraitPosition;
|
||||
use crate::{AllowReturnTypeNotation, ImplTraitPosition};
|
||||
|
||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
pub(crate) fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> {
|
||||
@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
qself,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
@ -55,6 +56,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
qself,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
@ -66,6 +68,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
qself,
|
||||
path,
|
||||
ParamMode::Optional,
|
||||
AllowReturnTypeNotation::No,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||
None,
|
||||
);
|
||||
|
@ -5,6 +5,7 @@ use rustc_hir::def::{DefKind, PartialRes, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::GenericArg;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_session::parse::add_feature_diagnostics;
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{BytePos, DesugaringKind, Span, Symbol, DUMMY_SP};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
@ -15,8 +16,8 @@ use super::errors::{
|
||||
GenericTypeWithParentheses, UseAngleBrackets,
|
||||
};
|
||||
use super::{
|
||||
GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode,
|
||||
ResolverAstLoweringExt,
|
||||
AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes,
|
||||
LoweringContext, ParamMode, ResolverAstLoweringExt,
|
||||
};
|
||||
use crate::ImplTraitPosition;
|
||||
|
||||
@ -28,6 +29,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
qself: &Option<ptr::P<QSelf>>,
|
||||
p: &Path,
|
||||
param_mode: ParamMode,
|
||||
allow_return_type_notation: AllowReturnTypeNotation,
|
||||
itctx: ImplTraitContext,
|
||||
// modifiers of the impl/bound if this is a trait path
|
||||
modifiers: Option<ast::TraitBoundModifiers>,
|
||||
@ -103,6 +105,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
{
|
||||
GenericArgsMode::ParenSugar
|
||||
}
|
||||
Res::Def(DefKind::AssocFn, _) if i + 1 == proj_start => {
|
||||
match allow_return_type_notation {
|
||||
AllowReturnTypeNotation::Yes => GenericArgsMode::ReturnTypeNotation,
|
||||
AllowReturnTypeNotation::No => GenericArgsMode::Err,
|
||||
}
|
||||
}
|
||||
// Avoid duplicated errors.
|
||||
Res::Err => GenericArgsMode::ParenSugar,
|
||||
// An error
|
||||
@ -164,11 +172,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
|
||||
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
|
||||
for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
|
||||
// If this is a type-dependent `T::method(..)`.
|
||||
let generic_args_mode = if i + 1 == p.segments.len()
|
||||
&& matches!(allow_return_type_notation, AllowReturnTypeNotation::Yes)
|
||||
{
|
||||
GenericArgsMode::ReturnTypeNotation
|
||||
} else {
|
||||
GenericArgsMode::Err
|
||||
};
|
||||
|
||||
let hir_segment = self.arena.alloc(self.lower_path_segment(
|
||||
p.span,
|
||||
segment,
|
||||
param_mode,
|
||||
GenericArgsMode::Err,
|
||||
generic_args_mode,
|
||||
itctx,
|
||||
None,
|
||||
));
|
||||
@ -238,6 +255,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
|
||||
}
|
||||
GenericArgs::Parenthesized(data) => match generic_args_mode {
|
||||
GenericArgsMode::ReturnTypeNotation => {
|
||||
let mut err = if !data.inputs.is_empty() {
|
||||
self.dcx().create_err(BadReturnTypeNotation::Inputs {
|
||||
span: data.inputs_span,
|
||||
})
|
||||
} else if let FnRetTy::Ty(ty) = &data.output {
|
||||
self.dcx().create_err(BadReturnTypeNotation::Output {
|
||||
span: data.inputs_span.shrink_to_hi().to(ty.span),
|
||||
})
|
||||
} else {
|
||||
self.dcx().create_err(BadReturnTypeNotation::NeedsDots {
|
||||
span: data.inputs_span,
|
||||
})
|
||||
};
|
||||
if !self.tcx.features().return_type_notation
|
||||
&& self.tcx.sess.is_nightly_build()
|
||||
{
|
||||
add_feature_diagnostics(
|
||||
&mut err,
|
||||
&self.tcx.sess,
|
||||
sym::return_type_notation,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
(
|
||||
GenericArgsCtor {
|
||||
args: Default::default(),
|
||||
constraints: &[],
|
||||
parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
|
||||
span: path_span,
|
||||
},
|
||||
false,
|
||||
)
|
||||
}
|
||||
GenericArgsMode::ParenSugar => self.lower_parenthesized_parameter_data(
|
||||
data,
|
||||
itctx,
|
||||
@ -279,7 +330,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
},
|
||||
GenericArgs::ParenthesizedElided(span) => {
|
||||
self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span });
|
||||
match generic_args_mode {
|
||||
GenericArgsMode::ReturnTypeNotation => {
|
||||
// Ok
|
||||
}
|
||||
GenericArgsMode::ParenSugar | GenericArgsMode::Err => {
|
||||
self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span });
|
||||
}
|
||||
}
|
||||
(
|
||||
GenericArgsCtor {
|
||||
args: Default::default(),
|
||||
|
@ -48,6 +48,8 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh
|
||||
|
||||
hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found}
|
||||
|
||||
hir_analysis_bad_return_type_notation_position = return type notation not allowed in this position yet
|
||||
|
||||
hir_analysis_cannot_capture_late_bound_const =
|
||||
cannot capture late-bound const parameter in {$what}
|
||||
.label = parameter defined here
|
||||
|
@ -1693,3 +1693,10 @@ pub(crate) struct CmseCallGeneric {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_bad_return_type_notation_position)]
|
||||
pub(crate) struct BadReturnTypeNotation {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
use tracing::{debug, debug_span, instrument};
|
||||
|
||||
use crate::bounds::Bounds;
|
||||
use crate::errors::{AmbiguousLifetimeBound, WildPatTy};
|
||||
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, WildPatTy};
|
||||
use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend};
|
||||
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
||||
use crate::middle::resolve_bound_vars as rbv;
|
||||
@ -1910,6 +1910,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
ty::BoundConstness::NotConst,
|
||||
)
|
||||
}
|
||||
// Deny any qpath types that were successfully lowered in AST lowering.
|
||||
Res::Def(DefKind::AssocFn, _)
|
||||
if let [.., _trait_segment, item_segment] = &path.segments[..]
|
||||
&& item_segment.args.is_some_and(|args| {
|
||||
matches!(
|
||||
args.parenthesized,
|
||||
hir::GenericArgsParentheses::ReturnTypeNotation
|
||||
)
|
||||
}) =>
|
||||
{
|
||||
let guar = self.dcx().emit_err(BadReturnTypeNotation { span: path.span });
|
||||
Ty::new_error(tcx, guar)
|
||||
}
|
||||
Res::PrimTy(prim_ty) => {
|
||||
assert_eq!(opt_self_ty, None);
|
||||
let _ = self.prohibit_generic_args(
|
||||
|
@ -10,17 +10,14 @@ trait Tr {
|
||||
fn foo<T: Tr>()
|
||||
where
|
||||
T::method(..): Send,
|
||||
//~^ ERROR return type notation not allowed in this position yet
|
||||
//~| ERROR expected type, found function
|
||||
//~^ ERROR expected type, found function
|
||||
<T as Tr>::method(..): Send,
|
||||
//~^ ERROR return type notation not allowed in this position yet
|
||||
//~| ERROR expected associated type, found associated function `Tr::method`
|
||||
{
|
||||
let _ = T::CONST::(..);
|
||||
//~^ ERROR return type notation not allowed in this position yet
|
||||
let _: T::method(..);
|
||||
//~^ ERROR return type notation not allowed in this position yet
|
||||
//~| ERROR expected type, found function
|
||||
//~^ ERROR expected type, found function
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,9 +1,3 @@
|
||||
error[E0575]: expected associated type, found associated function `Tr::method`
|
||||
--> $DIR/bare-path.rs:15:5
|
||||
|
|
||||
LL | <T as Tr>::method(..): Send,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ not a associated type
|
||||
|
||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/bare-path.rs:1:12
|
||||
|
|
||||
@ -14,29 +8,11 @@ LL | #![feature(return_type_notation)]
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: return type notation not allowed in this position yet
|
||||
--> $DIR/bare-path.rs:19:23
|
||||
--> $DIR/bare-path.rs:17:23
|
||||
|
|
||||
LL | let _ = T::CONST::(..);
|
||||
| ^^^^
|
||||
|
||||
error: return type notation not allowed in this position yet
|
||||
--> $DIR/bare-path.rs:21:21
|
||||
|
|
||||
LL | let _: T::method(..);
|
||||
| ^^^^
|
||||
|
||||
error: return type notation not allowed in this position yet
|
||||
--> $DIR/bare-path.rs:12:14
|
||||
|
|
||||
LL | T::method(..): Send,
|
||||
| ^^^^
|
||||
|
||||
error: return type notation not allowed in this position yet
|
||||
--> $DIR/bare-path.rs:15:22
|
||||
|
|
||||
LL | <T as Tr>::method(..): Send,
|
||||
| ^^^^
|
||||
|
||||
error: expected type, found function
|
||||
--> $DIR/bare-path.rs:12:8
|
||||
|
|
||||
@ -49,8 +25,14 @@ note: the associated function is defined here
|
||||
LL | fn method() -> impl Sized;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: return type notation not allowed in this position yet
|
||||
--> $DIR/bare-path.rs:14:5
|
||||
|
|
||||
LL | <T as Tr>::method(..): Send,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: expected type, found function
|
||||
--> $DIR/bare-path.rs:21:15
|
||||
--> $DIR/bare-path.rs:19:15
|
||||
|
|
||||
LL | let _: T::method(..);
|
||||
| ^^^^^^ unexpected function
|
||||
@ -61,6 +43,5 @@ note: the associated function is defined here
|
||||
LL | fn method() -> impl Sized;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 7 previous errors; 1 warning emitted
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0575`.
|
||||
|
@ -1,7 +1,7 @@
|
||||
pub fn foo(num: i32) -> i32 {
|
||||
let foo: i32::from_be(num);
|
||||
//~^ ERROR expected type, found local variable `num`
|
||||
//~| ERROR parenthesized type parameters may only be used with a `Fn` trait
|
||||
//~| ERROR argument types not allowed with return type notation
|
||||
//~| ERROR ambiguous associated type
|
||||
foo
|
||||
}
|
||||
|
@ -6,16 +6,15 @@ LL | let foo: i32::from_be(num);
|
||||
| |
|
||||
| help: use `=` if you meant to assign
|
||||
|
||||
error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
|
||||
--> $DIR/let-binding-init-expr-as-ty.rs:2:19
|
||||
error: argument types not allowed with return type notation
|
||||
--> $DIR/let-binding-init-expr-as-ty.rs:2:26
|
||||
|
|
||||
LL | let foo: i32::from_be(num);
|
||||
| ^^^^^^^^^^^^ only `Fn` traits may use parentheses
|
||||
| ^^^^^ help: remove the input types: `()`
|
||||
|
|
||||
help: use angle brackets instead
|
||||
|
|
||||
LL | let foo: i32::from_be<num>;
|
||||
| ~ ~
|
||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||
= help: add `#![feature(return_type_notation)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0223]: ambiguous associated type
|
||||
--> $DIR/let-binding-init-expr-as-ty.rs:2:14
|
||||
@ -30,5 +29,5 @@ LL | let foo: <i32 as Example>::from_be;
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0214, E0223, E0573.
|
||||
For more information about an error, try `rustc --explain E0214`.
|
||||
Some errors have detailed explanations: E0223, E0573.
|
||||
For more information about an error, try `rustc --explain E0223`.
|
||||
|
Loading…
Reference in New Issue
Block a user