1
Fork 0

Rollup merge of #86176 - nbdd0121:explicit-generic-args, r=jackh726

Implement a `explicit_generic_args_with_impl_trait` feature gate

Implements #83701

When this gate is enabled, explicit generic arguments can be specified even if `impl Trait` is used in argument position. Generic arguments can only be specified for explicit generic parameters but not for the synthetic type parameters from  `impl Trait`

So code like this will be accepted:
```rust
#![feature(explicit_generic_args_with_impl_trait)]

fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
fn main() {
    foo::<str>("".to_string());
}
```
This commit is contained in:
Cameron Steffen 2021-08-02 09:36:49 -05:00 committed by GitHub
commit 14f3418f79
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 139 additions and 4 deletions

View file

@ -459,7 +459,32 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let default_counts = gen_params.own_defaults();
let param_counts = gen_params.own_counts();
let named_type_param_count = param_counts.types - has_self as usize;
// Subtracting from param count to ensure type params synthesized from `impl Trait`
// cannot be explictly 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: Some(
hir::SyntheticTyParamKind::ImplTrait
| hir::SyntheticTyParamKind::FromAttr
),
..
}
)
})
.count()
} else {
0
};
let named_type_param_count =
param_counts.types - has_self as usize - synth_type_param_count;
let infer_lifetimes =
gen_pos != GenericArgPosition::Type && !gen_args.has_lifetime_params();
@ -588,6 +613,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
param_counts.consts + named_type_param_count
- default_counts.types
- default_counts.consts
- synth_type_param_count
};
debug!("expected_min: {:?}", expected_min);
debug!("arg_counts.lifetimes: {:?}", gen_args.num_lifetime_params());
@ -617,7 +643,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
seg: &hir::PathSegment<'_>,
generics: &ty::Generics,
) -> bool {
let explicit = !seg.infer_args;
if seg.infer_args || tcx.features().explicit_generic_args_with_impl_trait {
return false;
}
let impl_trait = generics.params.iter().any(|param| {
matches!(
param.kind,
@ -630,7 +659,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
)
});
if explicit && impl_trait {
if impl_trait {
let spans = seg
.args()
.args