Skip to content

Stabilize explicit_generic_args_with_impl_trait #96868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 11, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_error_codes/src/error_codes/E0632.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#### Note: this error code is no longer emitted by the compiler.

An explicit generic argument was provided when calling a function that
uses `impl Trait` in argument position.

Erroneous code example:

```compile_fail,E0632
```ignore (no longer an error)
fn foo<T: Copy>(a: T, b: impl Clone) {}

foo::<i32>(0i32, "abc".to_string());
6 changes: 0 additions & 6 deletions compiler/rustc_error_messages/locales/en-US/typeck.ftl
Original file line number Diff line number Diff line change
@@ -95,12 +95,6 @@ typeck-expected-return-type = expected `{$expected}` because of return type
typeck-unconstrained-opaque-type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same module

typeck-explicit-generic-args-with-impl-trait =
cannot provide explicit generic arguments when `impl Trait` is used in argument position
.label = explicit generic argument not allowed
.note = see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
.help = add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable

typeck-missing-type-params =
the type {$parameterCount ->
[one] parameter
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
@@ -142,6 +142,8 @@ declare_features! (
(accepted, dyn_trait, "1.27.0", Some(44662), None),
/// Allows integer match exhaustiveness checking (RFC 2591).
(accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
/// Allows explicit generic arguments specification with `impl Trait` present.
(accepted, explicit_generic_args_with_impl_trait, "1.63.0", Some(83701), None),
/// Allows arbitrary expressions in key-value attributes at parse time.
(accepted, extended_key_value_attributes, "1.54.0", Some(78835), None),
/// Allows resolving absolute paths as paths from other crates.
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -383,8 +383,6 @@ declare_features! (
(active, exclusive_range_pattern, "1.11.0", Some(37854), None),
/// Allows exhaustive pattern matching on types that contain uninhabited types.
(active, exhaustive_patterns, "1.13.0", Some(51085), None),
/// Allows explicit generic arguments specification with `impl Trait` present.
(active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None),
/// Allows defining `extern type`s.
(active, extern_types, "1.23.0", Some(43467), None),
/// Allows the use of `#[ffi_const]` on foreign functions.
70 changes: 18 additions & 52 deletions compiler/rustc_typeck/src/astconv/generics.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ use crate::astconv::{
AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
GenericArgCountResult, GenericArgPosition,
};
use crate::errors::{AssocTypeBindingNotAllowed, ExplicitGenericArgsWithImplTrait};
use crate::errors::AssocTypeBindingNotAllowed;
use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
use rustc_ast::ast::ParamKindOrd;
use rustc_errors::{struct_span_err, Applicability, Diagnostic, MultiSpan};
@@ -397,19 +397,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
is_method_call: IsMethodCall,
) -> GenericArgCountResult {
let empty_args = hir::GenericArgs::none();
let suppress_mismatch = Self::check_impl_trait(tcx, seg, generics);

let gen_args = seg.args.unwrap_or(&empty_args);
let gen_pos = if is_method_call == IsMethodCall::Yes {
GenericArgPosition::MethodCall
} else {
GenericArgPosition::Value
};
let has_self = generics.parent.is_none() && generics.has_self;
let infer_args = seg.infer_args || suppress_mismatch;

Self::check_generic_arg_count(
tcx, span, def_id, seg, generics, gen_args, gen_pos, has_self, infer_args,
tcx,
span,
def_id,
seg,
generics,
gen_args,
gen_pos,
has_self,
seg.infer_args,
)
}

@@ -431,19 +436,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let param_counts = gen_params.own_counts();

// Subtracting from param count to ensure type params synthesized from `impl Trait`
// cannot be explicitly specified even with `explicit_generic_args_with_impl_trait`
// feature enabled.
let synth_type_param_count = if tcx.features().explicit_generic_args_with_impl_trait {
gen_params
.params
.iter()
.filter(|param| {
matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. })
})
.count()
} else {
0
};
// cannot be explicitly specified.
let synth_type_param_count = gen_params
.params
.iter()
.filter(|param| {
matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. })
})
.count();
let named_type_param_count =
param_counts.types - has_self as usize - synth_type_param_count;
let infer_lifetimes =
@@ -611,40 +611,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}

/// Report error if there is an explicit type parameter when using `impl Trait`.
pub(crate) fn check_impl_trait(
tcx: TyCtxt<'_>,
seg: &hir::PathSegment<'_>,
generics: &ty::Generics,
) -> bool {
if seg.infer_args || tcx.features().explicit_generic_args_with_impl_trait {
return false;
}

let impl_trait = generics.has_impl_trait();

if impl_trait {
let spans = seg
.args()
.args
.iter()
.filter_map(|arg| match arg {
GenericArg::Infer(_) | GenericArg::Type(_) | GenericArg::Const(_) => {
Some(arg.span())
}
_ => None,
})
.collect::<Vec<_>>();

tcx.sess.emit_err(ExplicitGenericArgsWithImplTrait {
spans,
is_nightly_build: tcx.sess.is_nightly_build().then_some(()),
});
}

impl_trait
}

/// Emits an error regarding forbidden type binding associations
pub fn prohibit_assoc_ty_binding(tcx: TyCtxt<'_>, span: Span) {
tcx.sess.emit_err(AssocTypeBindingNotAllowed { span });
11 changes: 0 additions & 11 deletions compiler/rustc_typeck/src/errors.rs
Original file line number Diff line number Diff line change
@@ -241,17 +241,6 @@ pub struct UnconstrainedOpaqueType {
pub name: Symbol,
}

#[derive(SessionDiagnostic)]
#[error(code = "E0632", slug = "typeck-explicit-generic-args-with-impl-trait")]
#[note]
pub struct ExplicitGenericArgsWithImplTrait {
#[primary_span]
#[label]
pub spans: Vec<Span>,
#[help]
pub is_nightly_build: Option<()>,
}

pub struct MissingTypeParams {
pub span: Span,
pub def_span: Span,

This file was deleted.

12 changes: 0 additions & 12 deletions src/test/ui/const-generics/impl-trait-with-const-arguments.stderr

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// check-pass

trait Usizer {
fn m(self) -> usize;
}
@@ -16,5 +18,4 @@ impl Usizer for Usizable {

fn main() {
assert_eq!(f::<4usize>(Usizable), 20usize);
//~^ ERROR cannot provide explicit generic arguments when `impl Trait` is used in argument position
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(explicit_generic_args_with_impl_trait)]

fn foo<T: ?Sized>(_f: impl AsRef<T>) {}

fn main() {
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error[E0107]: this function takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/explicit-generic-args-for-impl.rs:6:5
--> $DIR/explicit-generic-args-for-impl.rs:4:5
|
LL | foo::<str, String>("".to_string());
| ^^^ ------ help: remove this generic argument
| |
| expected 1 generic argument
|
note: function defined here, with 1 generic parameter: `T`
--> $DIR/explicit-generic-args-for-impl.rs:3:4
--> $DIR/explicit-generic-args-for-impl.rs:1:4
|
LL | fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
| ^^^ -
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// check-pass

#![feature(explicit_generic_args_with_impl_trait)]

fn foo<T: ?Sized>(_f: impl AsRef<T>) {}

fn main() {

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// check-pass

#![feature(explicit_generic_args_with_impl_trait)]

fn f<T: ?Sized>(_: impl AsRef<T>, _: impl AsRef<T>) {}

fn main() {
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(explicit_generic_args_with_impl_trait)]

fn f<T: ?Sized, U: ?Sized>(_: impl AsRef<T>, _: impl AsRef<U>) {}

fn main() {
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
--> $DIR/not-enough-args.rs:6:5
--> $DIR/not-enough-args.rs:4:5
|
LL | f::<[u8]>("a", b"a");
| ^ ---- supplied 1 generic argument
| |
| expected 2 generic arguments
|
note: function defined here, with 2 generic parameters: `T`, `U`
--> $DIR/not-enough-args.rs:3:4
--> $DIR/not-enough-args.rs:1:4
|
LL | fn f<T: ?Sized, U: ?Sized>(_: impl AsRef<T>, _: impl AsRef<U>) {}
| ^ - -
7 changes: 0 additions & 7 deletions src/test/ui/impl-trait/issues/universal-issue-48703.rs

This file was deleted.

12 changes: 0 additions & 12 deletions src/test/ui/impl-trait/issues/universal-issue-48703.stderr

This file was deleted.

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion src/test/ui/inference/issue-83606.rs
Original file line number Diff line number Diff line change
@@ -5,6 +5,6 @@ fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] {
}

fn main() {
let _ = foo("foo"); //<- Do not suggest `foo::<N>("foo");`!
let _ = foo("foo");
//~^ ERROR: type annotations needed for `[usize; _]`
}
Loading