address review comments

I split the RFC1592 commit out
This commit is contained in:
Ariel Ben-Yehuda 2016-07-22 23:52:53 +03:00
parent 23bb1df1e5
commit 717e39294f
12 changed files with 74 additions and 85 deletions

View File

@ -196,12 +196,6 @@ pub enum TypeOrigin {
// FIXME(eddyb) #11161 is the original Expr required?
ExprAssignable(Span),
// Relating trait refs when resolving vtables
RelateTraitRefs(Span),
// Relating self types when resolving vtables
RelateSelfType(Span),
// Relating trait type parameters to those found in impl etc
RelateOutputImplTypes(Span),
@ -228,16 +222,17 @@ pub enum TypeOrigin {
// intrinsic has wrong type
IntrinsicType(Span),
// method receiver
MethodReceiver(Span),
}
impl TypeOrigin {
fn as_failure_str(&self) -> &'static str {
match self {
&TypeOrigin::Misc(_) |
&TypeOrigin::RelateSelfType(_) |
&TypeOrigin::RelateOutputImplTypes(_) |
&TypeOrigin::ExprAssignable(_) => "mismatched types",
&TypeOrigin::RelateTraitRefs(_) => "mismatched traits",
&TypeOrigin::MethodCompatCheck(_) => "method not compatible with trait",
&TypeOrigin::MatchExpressionArm(_, _, source) => match source {
hir::MatchSource::IfLetDesugar{..} => "`if let` arms have incompatible types",
@ -250,6 +245,7 @@ impl TypeOrigin {
&TypeOrigin::MainFunctionType(_) => "main function has wrong type",
&TypeOrigin::StartFunctionType(_) => "start function has wrong type",
&TypeOrigin::IntrinsicType(_) => "intrinsic has wrong type",
&TypeOrigin::MethodReceiver(_) => "mismatched method receiver",
}
}
@ -258,8 +254,6 @@ impl TypeOrigin {
&TypeOrigin::Misc(_) => "types are compatible",
&TypeOrigin::MethodCompatCheck(_) => "method type is compatible with trait",
&TypeOrigin::ExprAssignable(_) => "expression is assignable",
&TypeOrigin::RelateTraitRefs(_) => "traits are compatible",
&TypeOrigin::RelateSelfType(_) => "self type matches impl self type",
&TypeOrigin::RelateOutputImplTypes(_) => {
"trait type parameters matches those specified on the impl"
}
@ -271,6 +265,7 @@ impl TypeOrigin {
&TypeOrigin::MainFunctionType(_) => "`main` function has the correct type",
&TypeOrigin::StartFunctionType(_) => "`start` function has the correct type",
&TypeOrigin::IntrinsicType(_) => "intrinsic has the correct type",
&TypeOrigin::MethodReceiver(_) => "method receiver has the correct type",
}
}
}
@ -1806,8 +1801,6 @@ impl TypeOrigin {
TypeOrigin::MethodCompatCheck(span) => span,
TypeOrigin::ExprAssignable(span) => span,
TypeOrigin::Misc(span) => span,
TypeOrigin::RelateTraitRefs(span) => span,
TypeOrigin::RelateSelfType(span) => span,
TypeOrigin::RelateOutputImplTypes(span) => span,
TypeOrigin::MatchExpressionArm(match_span, _, _) => match_span,
TypeOrigin::IfExpression(span) => span,
@ -1817,6 +1810,7 @@ impl TypeOrigin {
TypeOrigin::MainFunctionType(span) => span,
TypeOrigin::StartFunctionType(span) => span,
TypeOrigin::IntrinsicType(span) => span,
TypeOrigin::MethodReceiver(span) => span,
}
}
}

View File

@ -384,15 +384,6 @@ pub fn note_const_eval_err<'a, 'tcx>(
diag.span_label(err.span, &message);
}
}
ConstEvalErrDescription::ExpectedFound { error, expected, found } => {
if check_old_school() {
diag.note(&error);
} else {
diag.span_label(err.span, &error);
}
diag.note(&format!("expected `{}`", expected));
diag.note(&format!("found `{}`", found));
}
}
if !primary_span.contains(err.span) {
@ -477,11 +468,6 @@ impl From<ConstMathErr> for ErrKind {
#[derive(Clone, Debug)]
pub enum ConstEvalErrDescription<'a> {
Simple(Cow<'a, str>),
ExpectedFound {
error: Cow<'a, str>,
expected: Cow<'a, str>,
found: Cow<'a, str>
}
}
impl<'a> ConstEvalErrDescription<'a> {
@ -489,14 +475,6 @@ impl<'a> ConstEvalErrDescription<'a> {
pub fn into_oneline(self) -> Cow<'a, str> {
match self {
ConstEvalErrDescription::Simple(simple) => simple,
ConstEvalErrDescription::ExpectedFound {
error,
expected,
found
} => {
format!("{}: expected `{}`, found `{}`", error, expected, found)
.into_cow()
}
}
}
}
@ -554,11 +532,7 @@ impl ConstEvalErr {
the constant evaluator"),
TypeMismatch(ref expected, ref got) => {
ExpectedFound {
error: "mismatched types".into_cow(),
expected: <&str>::into_cow(expected),
found: got.description().into_cow()
}
simple!("expected {}, found {}", expected, got.description())
},
BadType(ref i) => simple!("value of wrong type: {:?}", i),
ErroneousReferencedConstant(_) => simple!("could not evaluate referenced constant"),

View File

@ -33,7 +33,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
let origin = TypeOrigin::Misc(sp);
self.demand_eqtype_with_origin(TypeOrigin::Misc(sp), expected, actual);
}
pub fn demand_eqtype_with_origin(&self,
origin: TypeOrigin,
expected: Ty<'tcx>,
actual: Ty<'tcx>)
{
match self.eq_types(false, origin, actual, expected) {
Ok(InferOk { obligations, .. }) => {
// FIXME(#32730) propagate obligations

View File

@ -13,6 +13,7 @@ use constrained_type_params::{identify_constrained_type_params, Parameter};
use CrateCtxt;
use hir::def_id::DefId;
use middle::region::{CodeExtent};
use rustc::infer::TypeOrigin;
use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt};
@ -157,7 +158,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
}
}
fn check_trait_or_impl_item(&mut self, item_id: ast::NodeId, span: Span) {
fn check_trait_or_impl_item(&mut self,
item_id: ast::NodeId,
span: Span,
sig_if_method: Option<&hir::MethodSig>) {
let code = self.code.clone();
self.for_id(item_id, span).with_fcx(|fcx, this| {
let free_substs = &fcx.parameter_environment.free_substs;
@ -182,7 +186,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
let predicates = fcx.instantiate_bounds(span, free_substs, &method.predicates);
this.check_fn_or_method(fcx, span, &method_ty, &predicates,
free_id_outlive, &mut implied_bounds);
this.check_method_receiver(fcx, span, &method,
let sig_if_method = sig_if_method.expect("bad signature for method");
this.check_method_receiver(fcx, sig_if_method, &method,
free_id_outlive, self_ty);
}
ty::TypeTraitItem(assoc_type) => {
@ -405,20 +410,15 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
fn check_method_receiver<'fcx, 'tcx>(&mut self,
fcx: &FnCtxt<'fcx, 'gcx, 'tcx>,
span: Span,
method_sig: &hir::MethodSig,
method: &ty::Method<'tcx>,
free_id_outlive: CodeExtent,
self_ty: ty::Ty<'tcx>)
{
// check that the type of the method's receiver matches the
// method's first parameter.
let free_substs = &fcx.parameter_environment.free_substs;
let fty = fcx.instantiate_type_scheme(span, free_substs, &method.fty);
let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &fty.sig);
debug!("check_method_receiver({:?},cat={:?},self_ty={:?},sig={:?})",
method.name, method.explicit_self, self_ty, sig);
debug!("check_method_receiver({:?},cat={:?},self_ty={:?})",
method.name, method.explicit_self, self_ty);
let rcvr_ty = match method.explicit_self {
ty::ExplicitSelfCategory::Static => return,
@ -431,13 +431,23 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
}
ty::ExplicitSelfCategory::ByBox => fcx.tcx.mk_box(self_ty)
};
let span = method_sig.decl.inputs[0].pat.span;
let free_substs = &fcx.parameter_environment.free_substs;
let fty = fcx.instantiate_type_scheme(span, free_substs, &method.fty);
let sig = fcx.tcx.liberate_late_bound_regions(free_id_outlive, &fty.sig);
debug!("check_method_receiver: sig={:?}", sig);
let rcvr_ty = fcx.instantiate_type_scheme(span, free_substs, &rcvr_ty);
let rcvr_ty = fcx.tcx.liberate_late_bound_regions(free_id_outlive,
&ty::Binder(rcvr_ty));
debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);
fcx.demand_eqtype(span, rcvr_ty, sig.inputs[0]);
let origin = TypeOrigin::MethodReceiver(span);
fcx.demand_eqtype_with_origin(origin, rcvr_ty, sig.inputs[0]);
}
fn check_variances_for_type_defn(&self,
@ -552,13 +562,21 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
debug!("visit_trait_item: {:?}", trait_item);
self.check_trait_or_impl_item(trait_item.id, trait_item.span);
let method_sig = match trait_item.node {
hir::TraitItem_::MethodTraitItem(ref sig, _) => Some(sig),
_ => None
};
self.check_trait_or_impl_item(trait_item.id, trait_item.span, method_sig);
intravisit::walk_trait_item(self, trait_item)
}
fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
debug!("visit_impl_item: {:?}", impl_item);
self.check_trait_or_impl_item(impl_item.id, impl_item.span);
let method_sig = match impl_item.node {
hir::ImplItemKind::Method(ref sig, _) => Some(sig),
_ => None
};
self.check_trait_or_impl_item(impl_item.id, impl_item.span, method_sig);
intravisit::walk_impl_item(self, impl_item)
}
}

View File

@ -21,9 +21,7 @@ use std::{u8, u16, u32, u64, usize};
const A_I8_T
: [u32; (i8::MAX as i8 + 1u8) as usize]
//~^ ERROR constant evaluation error [E0080]
//~| mismatched types
//~| expected `i8`
//~| found `u8`
//~| expected i8, found u8
= [0; (i8::MAX as usize) + 1];

View File

@ -26,7 +26,7 @@ fn f_i8() {
Ok2,
OhNo = 0_u8,
//~^ ERROR E0080
//~| mismatched types
//~| expected i8, found u8
}
let x = A::Ok;
@ -39,7 +39,7 @@ fn f_u8() {
Ok2,
OhNo = 0_i8,
//~^ ERROR E0080
//~| mismatched types
//~| expected u8, found i8
}
let x = A::Ok;
@ -52,7 +52,7 @@ fn f_i16() {
Ok2,
OhNo = 0_u16,
//~^ ERROR E0080
//~| mismatched types
//~| expected i16, found u16
}
let x = A::Ok;
@ -65,7 +65,7 @@ fn f_u16() {
Ok2,
OhNo = 0_i16,
//~^ ERROR E0080
//~| mismatched types
//~| expected u16, found i16
}
let x = A::Ok;
@ -78,7 +78,7 @@ fn f_i32() {
Ok2,
OhNo = 0_u32,
//~^ ERROR E0080
//~| mismatched types
//~| expected i32, found u32
}
let x = A::Ok;
@ -91,7 +91,7 @@ fn f_u32() {
Ok2,
OhNo = 0_i32,
//~^ ERROR E0080
//~| mismatched types
//~| expected u32, found i32
}
let x = A::Ok;
@ -104,7 +104,7 @@ fn f_i64() {
Ok2,
OhNo = 0_u64,
//~^ ERROR E0080
//~| mismatched types
//~| expected i64, found u64
}
let x = A::Ok;
@ -117,7 +117,7 @@ fn f_u64() {
Ok2,
OhNo = 0_i64,
//~^ ERROR E0080
//~| mismatched types
//~| expected u64, found i64
}
let x = A::Ok;

View File

@ -14,15 +14,17 @@ struct Foo<'a,'b> {
}
impl<'a,'b> Foo<'a,'b> {
fn bar(self: Foo<'b,'a>) {}
//~^ ERROR mismatched types
fn bar(
self
//~^ ERROR mismatched method receiver
//~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>`
//~| lifetime mismatch
//~| ERROR mismatched types
//~| ERROR mismatched method receiver
//~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>`
//~| lifetime mismatch
: Foo<'b,'a>) {}
}
fn main() {}

View File

@ -14,11 +14,11 @@ struct Foo<'a> {
impl <'a> Foo<'a>{
fn bar(self: &mut Foo) {
//~^ mismatched types
//~^ mismatched method receiver
//~| expected type `&mut Foo<'a>`
//~| found type `&mut Foo<'_>`
//~| lifetime mismatch
//~| mismatched types
//~| mismatched method receiver
//~| expected type `&mut Foo<'a>`
//~| found type `&mut Foo<'_>`
//~| lifetime mismatch

View File

@ -12,7 +12,7 @@ struct S(String);
impl S {
fn f(self: *mut S) -> String { self.0 }
//~^ ERROR mismatched types
//~^ ERROR mismatched method receiver
}
fn main() { S("".to_owned()).f(); }

View File

@ -11,12 +11,10 @@
enum Foo {
A = 1i64,
//~^ ERROR constant evaluation error
//~| expected `isize`
//~| found `i64`
//~| expected isize, found i64
B = 2u8
//~^ ERROR constant evaluation error
//~| expected `isize`
//~| found `u8`
//~| expected isize, found u8
}
fn main() {}

View File

@ -39,14 +39,12 @@ fn main() {
//~| ERROR expected usize for repeat count, found string literal [E0306]
let f = [0; -4_isize];
//~^ ERROR constant evaluation error
//~| expected `usize`
//~| found `isize`
//~| expected usize, found isize
//~| ERROR mismatched types
//~| expected usize, found isize
let f = [0_usize; -1_isize];
//~^ ERROR constant evaluation error
//~| expected `usize`
//~| found `isize`
//~| expected usize, found isize
//~| ERROR mismatched types
//~| expected usize, found isize
struct G {

View File

@ -15,7 +15,7 @@ struct Foo {
}
impl Foo {
fn foo(self: isize, x: isize) -> isize { //~ ERROR mismatched types
fn foo(self: isize, x: isize) -> isize { //~ ERROR mismatched method receiver
self.f + x
}
}
@ -25,10 +25,10 @@ struct Bar<T> {
}
impl<T> Bar<T> {
fn foo(self: Bar<isize>, x: isize) -> isize { //~ ERROR mismatched types
fn foo(self: Bar<isize>, x: isize) -> isize { //~ ERROR mismatched method receiver
x
}
fn bar(self: &Bar<usize>, x: isize) -> isize { //~ ERROR mismatched types
fn bar(self: &Bar<usize>, x: isize) -> isize { //~ ERROR mismatched method receiver
x
}
}
@ -41,14 +41,14 @@ trait SomeTrait {
impl<'a, T> SomeTrait for &'a Bar<T> {
fn dummy1(self: &&'a Bar<T>) { }
fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched types
//~^ ERROR mismatched types
fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched method receiver
//~^ ERROR mismatched method receiver
fn dummy3(self: &&Bar<T>) {}
//~^ ERROR mismatched types
//~^ ERROR mismatched method receiver
//~| expected type `&&'a Bar<T>`
//~| found type `&&Bar<T>`
//~| lifetime mismatch
//~| ERROR mismatched types
//~| ERROR mismatched method receiver
//~| expected type `&&'a Bar<T>`
//~| found type `&&Bar<T>`
//~| lifetime mismatch