Skip to content

Commit 2641c4e

Browse files
committed
Merge pull request #670 from Manishearth/better-ice-fix
Make derive lint handle generics correctly
2 parents cd35b9e + 570b963 commit 2641c4e

File tree

4 files changed

+27
-43
lines changed

4 files changed

+27
-43
lines changed

src/derive.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rustc::lint::*;
2+
use rustc::middle::subst::Subst;
23
use rustc::middle::ty::TypeVariants;
34
use rustc::middle::ty::fast_reject::simplify_type;
45
use rustc::middle::ty;
@@ -70,16 +71,14 @@ impl LintPass for Derive {
7071

7172
impl LateLintPass for Derive {
7273
fn check_item(&mut self, cx: &LateContext, item: &Item) {
73-
let ast_ty_to_ty_cache = cx.tcx.ast_ty_to_ty_cache.borrow();
74-
7574
if_let_chain! {[
76-
let ItemImpl(_, _, ref ast_generics, Some(ref trait_ref), ref ast_ty, _) = item.node,
77-
let Some(&ty) = ast_ty_to_ty_cache.get(&ast_ty.id)
75+
let ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node
7876
], {
77+
let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty;
7978
if item.attrs.iter().any(is_automatically_derived) {
8079
check_hash_peq(cx, item.span, trait_ref, ty);
8180
}
82-
else if !ast_generics.is_lt_parameterized() {
81+
else {
8382
check_copy_clone(cx, item, trait_ref, ty);
8483
}
8584
}}
@@ -132,8 +131,9 @@ fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>,
132131
trait_ref: &TraitRef, ty: ty::Ty<'tcx>) {
133132
if match_path(&trait_ref.path, &CLONE_TRAIT_PATH) {
134133
let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, item.id);
134+
let subst_ty = ty.subst(cx.tcx, &parameter_environment.free_substs);
135135

136-
if ty.moves_by_default(&parameter_environment, item.span) {
136+
if subst_ty.moves_by_default(&parameter_environment, item.span) {
137137
return; // ty is not Copy
138138
}
139139

src/methods.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ impl LateLintPass for MethodsPass {
366366
return;
367367
}
368368

369-
if let ItemImpl(_, _, _, None, ref ty, ref items) = item.node {
369+
if let ItemImpl(_, _, _, None, _, ref items) = item.node {
370370
for implitem in items {
371371
let name = implitem.name;
372372
if let ImplItemKind::Method(ref sig, _) = implitem.node {
@@ -387,6 +387,7 @@ impl LateLintPass for MethodsPass {
387387
}
388388

389389
// check conventions w.r.t. conversion method names and predicates
390+
let ty = cx.tcx.lookup_item_type(cx.tcx.map.local_def_id(item.id)).ty;
390391
let is_copy = is_copy(cx, &ty, &item);
391392
for &(ref conv, self_kinds) in &CONVENTIONS {
392393
if conv.check(&name.as_str()) &&
@@ -412,12 +413,13 @@ impl LateLintPass for MethodsPass {
412413
if &name.as_str() == &"new" {
413414
let returns_self = if let FunctionRetTy::Return(ref ret_ty) = sig.decl.output {
414415
let ast_ty_to_ty_cache = cx.tcx.ast_ty_to_ty_cache.borrow();
415-
let ty = ast_ty_to_ty_cache.get(&ty.id);
416416
let ret_ty = ast_ty_to_ty_cache.get(&ret_ty.id);
417417

418-
match (ty, ret_ty) {
419-
(Some(&ty), Some(&ret_ty)) => ret_ty.walk().any(|t| t == ty),
420-
_ => false,
418+
if let Some(&ret_ty) = ret_ty {
419+
ret_ty.walk().any(|t| t == ty)
420+
}
421+
else {
422+
false
421423
}
422424
}
423425
else {
@@ -983,12 +985,7 @@ fn is_bool(ty: &Ty) -> bool {
983985
false
984986
}
985987

986-
fn is_copy(cx: &LateContext, ast_ty: &Ty, item: &Item) -> bool {
987-
match cx.tcx.ast_ty_to_ty_cache.borrow().get(&ast_ty.id) {
988-
None => false,
989-
Some(ty) => {
990-
let env = ty::ParameterEnvironment::for_item(cx.tcx, item.id);
991-
!ty.subst(cx.tcx, &env.free_substs).moves_by_default(&env, ast_ty.span)
992-
}
993-
}
988+
fn is_copy<'a, 'ctx>(cx: &LateContext<'a, 'ctx>, ty: ty::Ty<'ctx>, item: &Item) -> bool {
989+
let env = ty::ParameterEnvironment::for_item(cx.tcx, item.id);
990+
!ty.subst(cx.tcx, &env.free_substs).moves_by_default(&env, item.span)
994991
}

tests/compile-fail/derive.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ impl Clone for Qux {
3535
fn clone(&self) -> Self { Qux }
3636
}
3737

38+
// See #666
39+
#[derive(Copy)]
40+
struct Lt<'a> {
41+
a: &'a u8,
42+
}
43+
44+
impl<'a> Clone for Lt<'a> {
45+
//~^ ERROR you are implementing `Clone` explicitly on a `Copy` type
46+
fn clone(&self) -> Self { unimplemented!() }
47+
}
48+
3849
// Ok, `Clone` cannot be derived because of the big array
3950
#[derive(Copy)]
4051
struct BigArray {

tests/ice-666.rs

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)