From 6867d91d20a77ad9be4288829cedec2a8c2b72ba Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Thu, 10 Jul 2014 14:05:28 -0400 Subject: [PATCH] middle::kind: Don't crash when checking safety of Drop To verify that a type can satisfy Send `check_struct_safe_for_destructor` attempts to construct a new `ty::t` an empty substitution list. Previously the function would verify that the function has no type parameters before attempting this. Unfortunately this check would not catch functions with only regions parameters. In this case, the type would eventually find its way to the substition engine which would attempt to perform a substitution on the region parameters. As the constructed substitution list is empty, this would fail, leading to a compiler crash. We fix this by verifying that types have both no type and region parameters. --- src/librustc/middle/kind.rs | 3 ++- src/librustc/middle/ty.rs | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 98aef8ca4932..4f7cb742d8f8 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -87,7 +87,8 @@ fn check_struct_safe_for_destructor(cx: &mut Context, span: Span, struct_did: DefId) { let struct_tpt = ty::lookup_item_type(cx.tcx, struct_did); - if !struct_tpt.generics.has_type_params(subst::TypeSpace) { + if !struct_tpt.generics.has_type_params(subst::TypeSpace) + && !struct_tpt.generics.has_region_params(subst::TypeSpace) { let struct_ty = ty::mk_struct(cx.tcx, struct_did, subst::Substs::empty()); if !ty::type_is_sendable(cx.tcx, struct_ty) { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index fcc2f008fc6c..dc69e3fd6399 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -984,6 +984,10 @@ impl Generics { pub fn has_type_params(&self, space: subst::ParamSpace) -> bool { !self.types.is_empty_in(space) } + + pub fn has_region_params(&self, space: subst::ParamSpace) -> bool { + !self.regions.is_empty_in(space) + } } /// When type checking, we use the `ParameterEnvironment` to track