mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-18 03:25:55 +00:00
parent
d938ba4769
commit
243e45aac3
@ -147,35 +147,41 @@ impl<'tcx> ParameterEnvironment<'tcx> {
|
||||
self_type: Ty<'tcx>, span: Span)
|
||||
-> Result<(),CopyImplementationError> {
|
||||
// FIXME: (@jroesch) float this code up
|
||||
tcx.infer_ctxt(None, Some(self.clone()), Reveal::ExactMatch).enter(|infcx| {
|
||||
let adt = match self_type.sty {
|
||||
ty::TyAdt(adt, substs) => match adt.adt_kind() {
|
||||
AdtKind::Struct | AdtKind::Union => {
|
||||
for field in adt.all_fields() {
|
||||
let field_ty = field.ty(tcx, substs);
|
||||
if infcx.type_moves_by_default(field_ty, span) {
|
||||
return Err(CopyImplementationError::InfrigingField(
|
||||
field.name))
|
||||
}
|
||||
}
|
||||
adt
|
||||
}
|
||||
AdtKind::Enum => {
|
||||
for variant in &adt.variants {
|
||||
for field in &variant.fields {
|
||||
let field_ty = field.ty(tcx, substs);
|
||||
if infcx.type_moves_by_default(field_ty, span) {
|
||||
return Err(CopyImplementationError::InfrigingVariant(
|
||||
variant.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
adt
|
||||
}
|
||||
},
|
||||
tcx.infer_ctxt(None, Some(self.clone()), Reveal::NotSpecializable).enter(|infcx| {
|
||||
let (adt, substs) = match self_type.sty {
|
||||
ty::TyAdt(adt, substs) => (adt, substs),
|
||||
_ => return Err(CopyImplementationError::NotAnAdt)
|
||||
};
|
||||
|
||||
let field_implements_copy = |field: &ty::FieldDef| {
|
||||
let cause = traits::ObligationCause::dummy();
|
||||
match traits::fully_normalize(&infcx, cause, &field.ty(tcx, substs)) {
|
||||
Ok(ty) => !infcx.type_moves_by_default(ty, span),
|
||||
Err(..) => false
|
||||
}
|
||||
};
|
||||
|
||||
match adt.adt_kind() {
|
||||
AdtKind::Struct | AdtKind::Union => {
|
||||
for field in adt.all_fields() {
|
||||
if !field_implements_copy(field) {
|
||||
return Err(CopyImplementationError::InfrigingField(
|
||||
field.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
AdtKind::Enum => {
|
||||
for variant in &adt.variants {
|
||||
for field in &variant.fields {
|
||||
if !field_implements_copy(field) {
|
||||
return Err(CopyImplementationError::InfrigingVariant(
|
||||
variant.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if adt.has_dtor() {
|
||||
return Err(CopyImplementationError::HasDestructor);
|
||||
}
|
||||
|
27
src/test/run-pass/issue-33187.rs
Normal file
27
src/test/run-pass/issue-33187.rs
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
struct Foo<A: Repr>(<A as Repr>::Data);
|
||||
|
||||
impl<A> Copy for Foo<A> where <A as Repr>::Data: Copy { }
|
||||
impl<A> Clone for Foo<A> where <A as Repr>::Data: Clone {
|
||||
fn clone(&self) -> Self { Foo(self.0.clone()) }
|
||||
}
|
||||
|
||||
trait Repr {
|
||||
type Data;
|
||||
}
|
||||
|
||||
impl<A> Repr for A {
|
||||
type Data = u32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
Loading…
Reference in New Issue
Block a user