Skip to content
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

Refactor ty::FnSig to contain a &'tcx Slice<Ty<'tcx>> #38097

Merged
merged 2 commits into from
Dec 6, 2016
Merged
Show file tree
Hide file tree
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: 2 additions & 2 deletions src/librustc/middle/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for ExprVisitor<'a, 'gcx, 'tcx> {
let typ = self.infcx.tcx.tables().node_id_to_type(expr.id);
match typ.sty {
ty::TyFnDef(.., ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
let from = bare_fn_ty.sig.0.inputs[0];
let to = bare_fn_ty.sig.0.output;
let from = bare_fn_ty.sig.skip_binder().inputs()[0];
let to = bare_fn_ty.sig.skip_binder().output();
self.check_transmute(expr.span, from, to, expr.id);
}
_ => {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// The `Self` type is erased, so it should not appear in list of
// arguments or return type apart from the receiver.
let ref sig = self.item_type(method.def_id).fn_sig();
for &input_ty in &sig.0.inputs[1..] {
for input_ty in &sig.skip_binder().inputs()[1..] {
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
return Some(MethodViolationCode::ReferencesSelf);
}
}
if self.contains_illegal_self_type_reference(trait_def_id, sig.0.output) {
if self.contains_illegal_self_type_reference(trait_def_id, sig.output().skip_binder()) {
return Some(MethodViolationCode::ReferencesSelf);
}

Expand Down
14 changes: 3 additions & 11 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1368,21 +1368,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
ty::TyFnDef(.., &ty::BareFnTy {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
sig: ty::Binder(ty::FnSig {
inputs: _,
output: _,
variadic: false
})
ref sig,
}) |
ty::TyFnPtr(&ty::BareFnTy {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
sig: ty::Binder(ty::FnSig {
inputs: _,
output: _,
variadic: false
})
}) => {
ref sig
}) if !sig.variadic() => {
candidates.vec.push(FnPointerCandidate);
}

Expand Down
7 changes: 4 additions & 3 deletions src/librustc/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,14 +487,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)>
{
let arguments_tuple = match tuple_arguments {
TupleArgumentsFlag::No => sig.0.inputs[0],
TupleArgumentsFlag::Yes => self.intern_tup(&sig.0.inputs[..]),
TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
TupleArgumentsFlag::Yes =>
self.intern_tup(sig.skip_binder().inputs()),
};
let trait_ref = ty::TraitRef {
def_id: fn_trait_def_id,
substs: self.mk_substs_trait(self_ty, &[arguments_tuple]),
};
ty::Binder((trait_ref, sig.0.output))
ty::Binder((trait_ref, sig.skip_binder().output()))
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}

pub fn mk_fn_sig<I>(self, inputs: I, output: I::Item, variadic: bool)
-> <I::Item as InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>>::Output
where I: Iterator,
I::Item: InternIteratorElement<Ty<'tcx>, ty::FnSig<'tcx>>
{
inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig {
inputs_and_output: self.intern_type_list(xs),
variadic: variadic
})
}

pub fn mk_existential_predicates<I: InternAs<[ExistentialPredicate<'tcx>],
&'tcx Slice<ExistentialPredicate<'tcx>>>>(self, iter: I)
-> I::Output {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/fast_reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
Some(TupleSimplifiedType(tys.len()))
}
ty::TyFnDef(.., ref f) | ty::TyFnPtr(ref f) => {
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
Some(FunctionSimplifiedType(f.sig.skip_binder().inputs().len()))
}
ty::TyProjection(_) | ty::TyParam(_) => {
if can_simplify_params {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ impl FlagComputation {
fn add_fn_sig(&mut self, fn_sig: &ty::PolyFnSig) {
let mut computation = FlagComputation::new();

computation.add_tys(&fn_sig.0.inputs);
computation.add_ty(fn_sig.0.output);
computation.add_tys(fn_sig.skip_binder().inputs());
computation.add_ty(fn_sig.skip_binder().output());

self.add_bound_computation(&computation);
}
Expand Down
42 changes: 20 additions & 22 deletions src/librustc/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ use ty::subst::{Kind, Substs};
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::error::{ExpectedFound, TypeError};
use std::rc::Rc;
use std::iter;
use syntax::abi;
use hir as ast;
use rustc_data_structures::accumulate_vec::AccumulateVec;

pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>;

Expand Down Expand Up @@ -185,32 +187,28 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
expected_found(relation, &a.variadic, &b.variadic)));
}

let inputs = relate_arg_vecs(relation,
&a.inputs,
&b.inputs)?;
let output = relation.relate(&a.output, &b.output)?;
if a.inputs().len() != b.inputs().len() {
return Err(TypeError::ArgCount);
}

Ok(ty::FnSig {inputs: inputs,
output: output,
variadic: a.variadic})
let inputs_and_output = a.inputs().iter().cloned()
.zip(b.inputs().iter().cloned())
.map(|x| (x, false))
.chain(iter::once(((a.output(), b.output()), true)))
.map(|((a, b), is_output)| {
if is_output {
relation.relate(&a, &b)
} else {
relation.relate_with_variance(ty::Contravariant, &a, &b)
}
}).collect::<Result<AccumulateVec<[_; 8]>, _>>()?;
Ok(ty::FnSig {
inputs_and_output: relation.tcx().intern_type_list(&inputs_and_output),
variadic: a.variadic
})
}
}

fn relate_arg_vecs<'a, 'gcx, 'tcx, R>(relation: &mut R,
a_args: &[Ty<'tcx>],
b_args: &[Ty<'tcx>])
-> RelateResult<'tcx, Vec<Ty<'tcx>>>
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{
if a_args.len() != b_args.len() {
return Err(TypeError::ArgCount);
}

a_args.iter().zip(b_args)
.map(|(a, b)| relation.relate_with_variance(ty::Contravariant, a, b))
.collect()
}

impl<'tcx> Relate<'tcx> for ast::Unsafety {
fn relate<'a, 'gcx, R>(relation: &mut R,
a: &ast::Unsafety,
Expand Down
24 changes: 12 additions & 12 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,11 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
type Lifted = ty::FnSig<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
tcx.lift(&self.inputs[..]).and_then(|inputs| {
tcx.lift(&self.output).map(|output| {
ty::FnSig {
inputs: inputs,
output: output,
variadic: self.variadic
}
})
tcx.lift(&self.inputs_and_output).map(|x| {
ty::FnSig {
inputs_and_output: x,
variadic: self.variadic
}
})
}
}
Expand Down Expand Up @@ -589,17 +586,20 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {

impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::FnSig { inputs: self.inputs.fold_with(folder),
output: self.output.fold_with(folder),
variadic: self.variadic }
let inputs_and_output = self.inputs_and_output.fold_with(folder);
ty::FnSig {
inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output),
variadic: self.variadic,
}
}

fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
folder.fold_fn_sig(self)
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.inputs.visit_with(visitor) || self.output.visit_with(visitor)
self.inputs().iter().any(|i| i.visit_with(visitor)) ||
self.output().visit_with(visitor)
}
}

Expand Down
23 changes: 16 additions & 7 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,22 +563,31 @@ pub struct ClosureTy<'tcx> {
/// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct FnSig<'tcx> {
pub inputs: Vec<Ty<'tcx>>,
pub output: Ty<'tcx>,
pub inputs_and_output: &'tcx Slice<Ty<'tcx>>,
pub variadic: bool
}

impl<'tcx> FnSig<'tcx> {
pub fn inputs(&self) -> &[Ty<'tcx>] {
&self.inputs_and_output[..self.inputs_and_output.len() - 1]
}

pub fn output(&self) -> Ty<'tcx> {
self.inputs_and_output[self.inputs_and_output.len() - 1]
}
}

pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;

impl<'tcx> PolyFnSig<'tcx> {
pub fn inputs(&self) -> ty::Binder<Vec<Ty<'tcx>>> {
self.map_bound_ref(|fn_sig| fn_sig.inputs.clone())
pub fn inputs(&self) -> Binder<&[Ty<'tcx>]> {
Binder(self.skip_binder().inputs())
}
pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
self.map_bound_ref(|fn_sig| fn_sig.inputs[index])
self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
}
pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
self.map_bound_ref(|fn_sig| fn_sig.output.clone())
self.map_bound_ref(|fn_sig| fn_sig.output().clone())
}
pub fn variadic(&self) -> bool {
self.skip_binder().variadic
Expand Down Expand Up @@ -1243,7 +1252,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}

// Type accessors for substructures of types
pub fn fn_args(&self) -> ty::Binder<Vec<Ty<'tcx>>> {
pub fn fn_args(&self) -> ty::Binder<&[Ty<'tcx>]> {
self.fn_sig().inputs()
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
self.hash(f.unsafety);
self.hash(f.abi);
self.hash(f.sig.variadic());
self.hash(f.sig.inputs().skip_binder().len());
self.hash(f.sig.skip_binder().inputs().len());
}
TyDynamic(ref data, ..) => {
if let Some(p) = data.principal() {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,6 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
}

fn push_sig_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, sig: &ty::PolyFnSig<'tcx>) {
stack.push(sig.0.output);
stack.extend(sig.0.inputs.iter().cloned().rev());
stack.push(sig.skip_binder().output());
stack.extend(sig.skip_binder().inputs().iter().cloned().rev());
}
4 changes: 2 additions & 2 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "fn")?;
fn_sig(f, &self.inputs, self.variadic, self.output)
fn_sig(f, self.inputs(), self.variadic, self.output())
}
}

Expand Down Expand Up @@ -625,7 +625,7 @@ impl fmt::Debug for ty::RegionVid {

impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
write!(f, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic, self.output())
}
}

Expand Down
7 changes: 1 addition & 6 deletions src/librustc_driver/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,15 +265,10 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
}

pub fn t_fn(&self, input_tys: &[Ty<'tcx>], output_ty: Ty<'tcx>) -> Ty<'tcx> {
let input_args = input_tys.iter().cloned().collect();
self.infcx.tcx.mk_fn_ptr(self.infcx.tcx.mk_bare_fn(ty::BareFnTy {
unsafety: hir::Unsafety::Normal,
abi: Abi::Rust,
sig: ty::Binder(ty::FnSig {
inputs: input_args,
output: output_ty,
variadic: false,
}),
sig: ty::Binder(self.infcx.tcx.mk_fn_sig(input_tys.iter().cloned(), output_ty, false)),
}))
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1084,8 +1084,8 @@ impl LateLintPass for MutableTransmutes {
let typ = cx.tcx.tables().node_id_to_type(expr.id);
match typ.sty {
ty::TyFnDef(.., ref bare_fn) if bare_fn.abi == RustIntrinsic => {
let from = bare_fn.sig.0.inputs[0];
let to = bare_fn.sig.0.output;
let from = bare_fn.sig.skip_binder().inputs()[0];
let to = bare_fn.sig.skip_binder().output();
return Some((&from.sty, &to.sty));
}
_ => (),
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_lint/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,16 +603,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}

let sig = cx.erase_late_bound_regions(&bare_fn.sig);
if !sig.output.is_nil() {
let r = self.check_type_for_ffi(cache, sig.output);
if !sig.output().is_nil() {
let r = self.check_type_for_ffi(cache, sig.output());
match r {
FfiSafe => {}
_ => {
return r;
}
}
}
for arg in sig.inputs {
for arg in sig.inputs() {
let r = self.check_type_for_ffi(cache, arg);
match r {
FfiSafe => {}
Expand Down Expand Up @@ -678,12 +678,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
let sig = self.cx.tcx.item_type(def_id).fn_sig();
let sig = self.cx.tcx.erase_late_bound_regions(&sig);

for (&input_ty, input_hir) in sig.inputs.iter().zip(&decl.inputs) {
self.check_type_for_ffi_and_report_errors(input_hir.ty.span, &input_ty);
for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
self.check_type_for_ffi_and_report_errors(input_hir.ty.span, input_ty);
}

if let hir::Return(ref ret_hir) = decl.output {
let ret_ty = sig.output;
let ret_ty = sig.output();
if !ret_ty.is_nil() {
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let diverges = match ty.sty {
ty::TyFnDef(_, _, ref f) | ty::TyFnPtr(ref f) => {
// FIXME(canndrew): This is_never should probably be an is_uninhabited
f.sig.0.output.is_never()
f.sig.skip_binder().output().is_never()
}
_ => false
};
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/hair/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
span_bug!(expr.span, "method call has late-bound regions")
});

assert_eq!(sig.inputs.len(), 2);
assert_eq!(sig.inputs().len(), 2);

let tupled_args = Expr {
ty: sig.inputs[1],
ty: sig.inputs()[1],
temp_lifetime: temp_lifetime,
span: expr.span,
kind: ExprKind::Tuple {
Expand Down
Loading