Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
edc8c76
add tests for the arbitrary_self_types, which won't pass yet
mikeyhew Oct 20, 2017
497397a
initial implementation of arbitrary_self_types
mikeyhew Nov 2, 2017
7dff08d
Rewrote check_method_receiver and ExplicitSelf, got a borrow checker …
mikeyhew Nov 5, 2017
a3f5866
Fix the lifetime error in ExplicitSelf
mikeyhew Nov 5, 2017
9a592e6
Improve feature gate error, and return after emitting errors instead …
mikeyhew Nov 5, 2017
d03eb2c
Fix some of the tests
mikeyhew Nov 5, 2017
aa0df3d
get the old error messages back
mikeyhew Nov 6, 2017
6fd2156
Add arbitrary_self_types feature gate error to some tests
mikeyhew Nov 7, 2017
0d739b5
Update/improve documentation of ExpliciSelf
mikeyhew Nov 7, 2017
1d29966
wrap error code in DiagnosticId::Error so it compiles
mikeyhew Nov 7, 2017
0b27dcc
modify ExplicitSelf::determine to take an `is_self_type` predicate cl…
mikeyhew Nov 8, 2017
3902643
move ExplicitSelf to rustc::ty::util, and use it to implement object …
mikeyhew Nov 8, 2017
2369746
normalize associated types in both self_ty and self_arg_ty
mikeyhew Nov 8, 2017
bbe755c
Switch from using At::eq to InferCtxt::can_eq and demand_eqtype_with_…
mikeyhew Nov 8, 2017
02ce3ac
add a NOTE comment to the object safety test so that it passes
mikeyhew Nov 8, 2017
e06cd31
Remove the error check that I think is redundant, and change the test…
mikeyhew Nov 8, 2017
0a3a46d
tidy things up a bit
mikeyhew Nov 8, 2017
0954e54
shorten line length for tidy
mikeyhew Nov 8, 2017
aa00f17
fix error message in arbitrary-self-types-not-object-safe test
mikeyhew Nov 8, 2017
7f8b003
update ui test to new error message
mikeyhew Nov 8, 2017
dcbb27a
fix the bug in region_inference where constraint origins were being o…
mikeyhew Nov 9, 2017
31d3783
fixed all the compile-fail error messages
mikeyhew Nov 9, 2017
c046fda
update test/ui/static-lifetime.stderr with new error message
mikeyhew Nov 9, 2017
5d170f0
add a comment explaining the bugfix to infer::region_inference::add_c…
mikeyhew Nov 9, 2017
ddc21d5
Don't emit the feature error if it's an invalid self type
mikeyhew Nov 9, 2017
77cd993
add run-pass tests
mikeyhew Nov 9, 2017
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
Prev Previous commit
Next Next commit
Fix the lifetime error in ExplicitSelf
Had to take the infer context as a parameter instead of the type
context, so that the function can be called during inference
  • Loading branch information
mikeyhew committed Nov 7, 2017
commit a3f5866fe87a02254a3d4ab1debaa9e1ee460990
26 changes: 11 additions & 15 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use hir::def::Def;
use hir::def_id::DefId;
use middle::resolve_lifetime as rl;
use namespace::Namespace;
use rustc::infer::InferCtxt;
use rustc::ty::subst::{Kind, Subst, Substs};
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
Expand Down Expand Up @@ -1433,26 +1434,21 @@ impl<'tcx> ExplicitSelf<'tcx> {
/// ```
///
pub fn determine<'a, 'gcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
self_ty: Ty<'a>,
self_arg_ty: Ty<'a>
self_ty: Ty<'tcx>,
self_arg_ty: Ty<'tcx>
) -> ExplicitSelf<'tcx>
{
use self::ExplicitSelf::*;

tcx.infer_ctxt().enter(|infcx| {
let can_eq = |expected, actual| {
let cause = traits::ObligationCause::dummy();
infcx.at(&cause, param_env).eq(expected, actual).is_ok()
};
let can_eq = |expected, actual| infcx.can_eq(param_env, expected, actual).is_ok();

match self_arg_ty.sty {
_ if can_eq(self_arg_ty, self_ty) => ByValue,
ty::TyRef(region, ty::TypeAndMut { ty, mutbl}) if can_eq(ty, self_ty) => ByReference(region, mutbl),
ty::TyAdt(def, _) if def.is_box() && can_eq(self_arg_ty.boxed_ty(), self_ty) => ByBox,
_ => Other
}
})
match self_arg_ty.sty {
_ if can_eq(self_arg_ty, self_ty) => ByValue,
ty::TyRef(region, ty::TypeAndMut { ty, mutbl}) if can_eq(ty, self_ty) => ByReference(region, mutbl),
ty::TyAdt(def, _) if def.is_box() && can_eq(self_arg_ty.boxed_ty(), self_ty) => ByBox,
_ => Other
}
}
}
14 changes: 8 additions & 6 deletions src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,12 +505,14 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let self_arg_ty = *tcx.fn_sig(method.def_id).input(0).skip_binder();
let param_env = ty::ParamEnv::empty(Reveal::All);

match ExplicitSelf::determine(tcx, param_env, untransformed_self_ty, self_arg_ty) {
ExplicitSelf::ByValue => "self".to_string(),
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(),
ExplicitSelf::ByReference(_, hir::MutMutable) => "&mut self".to_string(),
_ => format!("self: {}", self_arg_ty)
}
tcx.infer_ctxt().enter(|infcx| {
match ExplicitSelf::determine(&infcx, param_env, untransformed_self_ty, self_arg_ty) {
ExplicitSelf::ByValue => "self".to_string(),
ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_string(),
ExplicitSelf::ByReference(_, hir::MutMutable) => "&mut self".to_string(),
_ => format!("self: {}", self_arg_ty)
}
})
};

match (trait_m.method_has_self_argument, impl_m.method_has_self_argument) {
Expand Down
9 changes: 5 additions & 4 deletions src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,25 +471,26 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> {
let self_arg_ty = sig.inputs()[0];

let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver);
let at = fcx.at(&cause, fcx.param_env);
let eq = |expected, actual| fcx.at(&cause, fcx.param_env).eq(expected, actual);
let mut autoderef = fcx.autoderef(span, self_arg_ty);

loop {
if let Some((potential_self_ty, _)) = autoderef.next() {
debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`", potential_self_ty, self_ty);

if let Ok(InferOk { obligations, value: () }) = at.eq(self_ty, potential_self_ty) {
if let Ok(InferOk { obligations, value: () }) = eq(self_ty, potential_self_ty) {
fcx.register_predicates(obligations);
autoderef.finalize();
break;
}

} else {
span_err!(fcx.tcx.sess, span, E0307, "invalid self type: {:?}", self_arg_ty);
span_err!(fcx.tcx.sess, span, E0307, "invalid `self` type: {:?}", self_arg_ty);
return;
}
}

if let ExplicitSelf::Other = ExplicitSelf::determine(fcx.tcx, fcx.param_env, self_ty, self_arg_ty) {
if let ExplicitSelf::Other = ExplicitSelf::determine(fcx, fcx.param_env, self_ty, self_arg_ty) {
if !fcx.tcx.sess.features.borrow().arbitrary_self_types {
fcx.tcx.sess.span_err(span, "Arbitrary `self` types are experimental");
}
Expand Down