Skip to content

Commit 51cd061

Browse files
committed
Auto merge of #44866 - mdevlamynck:impl-trait, r=eddyb
First step toward implementing impl Trait in argument position First step implementing #44721. Add a flag to hir and ty TypeParameterDef and raise an error when using explicit type parameters when calling a function using impl Trait in argument position. I don't know if there is a procedure to add an error code so I just took an available code. Is that ok ? r? @nikomatsakis
2 parents 09ee9b7 + 838105f commit 51cd061

File tree

10 files changed

+102
-2
lines changed

10 files changed

+102
-2
lines changed

src/librustc/hir/lowering.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,10 @@ impl<'a> LoweringContext<'a> {
11031103
default: tp.default.as_ref().map(|x| self.lower_ty(x)),
11041104
span: tp.span,
11051105
pure_wrt_drop: tp.attrs.iter().any(|attr| attr.check_name("may_dangle")),
1106+
synthetic: tp.attrs.iter()
1107+
.filter(|attr| attr.check_name("rustc_synthetic"))
1108+
.map(|_| hir::SyntheticTyParamKind::ImplTrait)
1109+
.nth(0),
11061110
}
11071111
}
11081112

src/librustc/hir/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ pub struct TyParam {
351351
pub default: Option<P<Ty>>,
352352
pub span: Span,
353353
pub pure_wrt_drop: bool,
354+
pub synthetic: Option<SyntheticTyParamKind>,
354355
}
355356

356357
/// Represents lifetimes and type parameters attached to a declaration
@@ -419,6 +420,13 @@ impl Generics {
419420
}
420421
}
421422

423+
/// Synthetic Type Parameters are converted to an other form during lowering, this allows
424+
/// to track the original form they had. Usefull for error messages.
425+
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
426+
pub enum SyntheticTyParamKind {
427+
ImplTrait
428+
}
429+
422430
/// A `where` clause in a definition
423431
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
424432
pub struct WhereClause {

src/librustc/ich/impls_hir.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ impl_stable_hash_for!(struct hir::TyParam {
177177
bounds,
178178
default,
179179
span,
180-
pure_wrt_drop
180+
pure_wrt_drop,
181+
synthetic
181182
});
182183

183184
impl_stable_hash_for!(struct hir::Generics {
@@ -187,6 +188,10 @@ impl_stable_hash_for!(struct hir::Generics {
187188
span
188189
});
189190

191+
impl_stable_hash_for!(enum hir::SyntheticTyParamKind {
192+
ImplTrait
193+
});
194+
190195
impl_stable_hash_for!(struct hir::WhereClause {
191196
id,
192197
predicates

src/librustc/ich/impls_ty.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,8 @@ impl_stable_hash_for!(struct ty::TypeParameterDef {
463463
index,
464464
has_default,
465465
object_lifetime_default,
466-
pure_wrt_drop
466+
pure_wrt_drop,
467+
synthetic
467468
});
468469

469470
impl<'gcx, T> HashStable<StableHashingContext<'gcx>>

src/librustc/ty/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,8 @@ pub struct TypeParameterDef {
675675
/// on generic parameter `T`, asserts data behind the parameter
676676
/// `T` won't be accessed during the parent type's `Drop` impl.
677677
pub pure_wrt_drop: bool,
678+
679+
pub synthetic: Option<hir::SyntheticTyParamKind>,
678680
}
679681

680682
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]

src/librustc_typeck/check/mod.rs

+31
Original file line numberDiff line numberDiff line change
@@ -4647,6 +4647,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
46474647
// a problem.
46484648
self.check_path_parameter_count(span, &mut type_segment, false);
46494649
self.check_path_parameter_count(span, &mut fn_segment, false);
4650+
self.check_impl_trait(span, &mut fn_segment);
46504651

46514652
let (fn_start, has_self) = match (type_segment, fn_segment) {
46524653
(_, Some((_, generics))) => {
@@ -4871,6 +4872,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
48714872
}
48724873
}
48734874

4875+
/// Report error if there is an explicit type parameter when using `impl Trait`.
4876+
fn check_impl_trait(&self,
4877+
span: Span,
4878+
segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
4879+
use hir::SyntheticTyParamKind::*;
4880+
4881+
segment.map(|(path_segment, generics)| {
4882+
let explicit = !path_segment.infer_types;
4883+
let impl_trait = generics.types.iter()
4884+
.any(|ty_param| {
4885+
match ty_param.synthetic {
4886+
Some(ImplTrait) => true,
4887+
_ => false,
4888+
}
4889+
});
4890+
4891+
if explicit && impl_trait {
4892+
let mut err = struct_span_err! {
4893+
self.tcx.sess,
4894+
span,
4895+
E0632,
4896+
"cannot provide explicit type parameters when `impl Trait` is \
4897+
used in argument position."
4898+
};
4899+
4900+
err.emit();
4901+
}
4902+
});
4903+
}
4904+
48744905
fn structurally_resolve_type_or_else<F>(&self, sp: Span, ty: Ty<'tcx>, f: F)
48754906
-> Ty<'tcx>
48764907
where F: Fn() -> Ty<'tcx>

src/librustc_typeck/collect.rs

+3
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
922922
has_default: false,
923923
object_lifetime_default: rl::Set1::Empty,
924924
pure_wrt_drop: false,
925+
synthetic: None,
925926
});
926927

927928
allow_defaults = true;
@@ -993,6 +994,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
993994
object_lifetime_default:
994995
object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]),
995996
pure_wrt_drop: p.pure_wrt_drop,
997+
synthetic: p.synthetic,
996998
}
997999
});
9981000
let mut types: Vec<_> = opt_self.into_iter().chain(types).collect();
@@ -1009,6 +1011,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
10091011
has_default: false,
10101012
object_lifetime_default: rl::Set1::Empty,
10111013
pure_wrt_drop: false,
1014+
synthetic: None,
10121015
}));
10131016
});
10141017
}

src/librustc_typeck/diagnostics.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4677,4 +4677,6 @@ register_diagnostics! {
46774677
E0592, // duplicate definitions with name `{}`
46784678
// E0613, // Removed (merged with E0609)
46794679
E0627, // yield statement outside of generator literal
4680+
E0632, // cannot provide explicit type parameters when `impl Trait` is used in
4681+
// argument position.
46804682
}

src/libsyntax/feature_gate.rs

+6
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,12 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
727727
is just used for rustc unit tests \
728728
and will never be stable",
729729
cfg_fn!(rustc_attrs))),
730+
("rustc_synthetic", Whitelisted, Gated(Stability::Unstable,
731+
"rustc_attrs",
732+
"this attribute \
733+
is just used for rustc unit tests \
734+
and will never be stable",
735+
cfg_fn!(rustc_attrs))),
730736
("rustc_symbol_name", Whitelisted, Gated(Stability::Unstable,
731737
"rustc_attrs",
732738
"internal rustc attributes will never be stable",
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(generic_param_attrs, rustc_attrs)]
12+
13+
fn func<#[rustc_synthetic] T>(_: T) {}
14+
15+
struct Foo;
16+
17+
impl Foo {
18+
pub fn func<#[rustc_synthetic] T>(_: T) {}
19+
}
20+
21+
struct Bar<S> {
22+
t: S
23+
}
24+
25+
impl<S> Bar<S> {
26+
pub fn func<#[rustc_synthetic] T>(_: T) {}
27+
}
28+
29+
fn main() {
30+
func::<u8>(42); //~ ERROR cannot provide explicit type parameters
31+
func(42); // Ok
32+
33+
Foo::func::<u8>(42); //~ ERROR cannot provide explicit type parameters
34+
Foo::func(42); // Ok
35+
36+
Bar::<i8>::func::<u8>(42); //~ ERROR cannot provide explicit type parameters
37+
Bar::<i8>::func(42); // Ok
38+
}

0 commit comments

Comments
 (0)