diff options
| -rw-r--r-- | src/librustc_typeck/check/closure.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 122 | ||||
| -rw-r--r-- | src/librustc_typeck/collect.rs | 1 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/trait-static-method-generic-inference.rs (renamed from src/test/run-pass/trait-static-method-generic-inference.rs) | 21 |
5 files changed, 48 insertions, 102 deletions
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 85ead053d1d..eba040e7ea8 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -48,7 +48,7 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, match expected_sig_and_kind { None => { // doesn't look like an unboxed closure let region = astconv::opt_ast_region_to_region(fcx, - fcx.infcx(), + fcx, expr.span, &None); @@ -117,7 +117,7 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, abi::RustCall, expected_sig); - let region = match fcx.infcx().anon_regions(expr.span, 1) { + let region = match fcx.anon_regions(expr.span, 1) { Err(_) => { fcx.ccx.tcx.sess.span_bug(expr.span, "can't make anon regions here?!") diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 12ecfe6c298..8069d00dda8 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1933,7 +1933,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn to_ty(&self, ast_t: &ast::Ty) -> Ty<'tcx> { - let t = ast_ty_to_ty(self, self.infcx(), ast_t); + let t = ast_ty_to_ty(self, self, ast_t); let mut bounds_checker = wf::BoundsChecker::new(self, ast_t.span, @@ -2123,18 +2123,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -//impl<'a, 'tcx> RegionScope for infer::InferCtxt<'a, 'tcx> { -// fn default_region_bound(&self, span: Span) -> Option<ty::Region> { -// Some(self.next_region_var(infer::MiscVariable(span))) -// } -// -// fn anon_regions(&self, span: Span, count: uint) -// -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>> { -// Ok(Vec::from_fn(count, |_| { -// self.next_region_var(infer::MiscVariable(span)) -// })) -// } -//} +impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> { + fn default_region_bound(&self, span: Span) -> Option<ty::Region> { + Some(self.infcx().next_region_var(infer::MiscVariable(span))) + } + + fn anon_regions(&self, span: Span, count: uint) + -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>> { + Ok(Vec::from_fn(count, |_| { + self.infcx().next_region_var(infer::MiscVariable(span)) + })) + } +} #[deriving(Copy, Show, PartialEq, Eq)] pub enum LvaluePreference { @@ -2347,58 +2347,6 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>, } } -/// Autoderefs `base_expr`, looking for a `Slice` impl. If it finds one, installs the relevant -/// method info and returns the result type (else None). -fn try_overloaded_slice<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, - method_call: MethodCall, - expr: &ast::Expr, - base_expr: &ast::Expr, - base_ty: Ty<'tcx>, - start_expr: &Option<P<ast::Expr>>, - end_expr: &Option<P<ast::Expr>>, - mutbl: ast::Mutability) - -> Option<Ty<'tcx>> // return type is result of slice -{ - let lvalue_pref = match mutbl { - ast::MutMutable => PreferMutLvalue, - ast::MutImmutable => NoPreference - }; - - let opt_method_ty = - autoderef_for_index(fcx, base_expr, base_ty, lvalue_pref, |adjusted_ty, autoderefref| { - try_overloaded_slice_step(fcx, method_call, expr, base_expr, - adjusted_ty, autoderefref, mutbl, - start_expr, end_expr) - }); - - // Regardless of whether the lookup succeeds, check the method arguments - // so that we have *some* type for each argument. - let method_ty_or_err = opt_method_ty.unwrap_or(fcx.tcx().types.err); - - let mut args = vec![]; - start_expr.as_ref().map(|x| args.push(x)); - end_expr.as_ref().map(|x| args.push(x)); - - check_method_argument_types(fcx, - expr.span, - method_ty_or_err, - expr, - args.as_slice(), - AutorefArgs::Yes, - DontTupleArguments); - - opt_method_ty.map(|method_ty| { - let result_ty = ty::ty_fn_ret(method_ty); - match result_ty { - ty::FnConverging(result_ty) => result_ty, - ty::FnDiverging => { - fcx.tcx().sess.span_bug(expr.span, - "slice trait does not define a `!` return") - } - } - }) -} - /// Checks for a `Slice` (or `SliceMut`) impl at the relevant level of autoderef. If it finds one, /// installs method info and returns type of method (else None). fn try_overloaded_slice_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, @@ -4327,7 +4275,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let actual_structure_type = fcx.expr_ty(&*expr); if !ty::type_is_error(actual_structure_type) { let type_and_substs = astconv::ast_path_to_ty_relaxed(fcx, - fcx.infcx(), + fcx, struct_id, path); match fcx.mk_subty(false, @@ -4410,8 +4358,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, }, base_t, None); - fcx.write_ty(idx.id, ty::mk_err()); - fcx.write_ty(id, ty::mk_err()) + fcx.write_ty(idx.id, fcx.tcx().types.err); + fcx.write_ty(id, fcx.tcx().types.err); } } } @@ -4440,7 +4388,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, fcx.write_ty(id, element_ty); } _ => { - check_expr_has_type(fcx, &**idx, ty::mk_err()); + check_expr_has_type(fcx, &**idx, fcx.tcx().types.err); fcx.type_error_message( expr.span, |actual| { @@ -4449,7 +4397,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, }, base_t, None); - fcx.write_ty(id, ty::mk_err()) + fcx.write_ty(id, fcx.tcx().types.err); } } } @@ -4468,19 +4416,21 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, }); let idx_type = match (t_start, t_end) { - (Some(ty), None) | (None, Some(ty)) => Some(ty), - (Some(t_start), Some(t_end)) - if ty::type_is_error(t_start) || ty::type_is_error(t_end) => { - Some(ty::mk_err()) - } - (Some(t_start), Some(t_end)) => { - Some(infer::common_supertype(fcx.infcx(), - infer::RangeExpression(expr.span), - true, - t_start, - t_end)) - } - _ => None + (Some(ty), None) | (None, Some(ty)) => { + Some(ty) + } + (Some(t_start), Some(t_end)) if (ty::type_is_error(t_start) || + ty::type_is_error(t_end)) => { + Some(fcx.tcx().types.err) + } + (Some(t_start), Some(t_end)) => { + Some(infer::common_supertype(fcx.infcx(), + infer::RangeExpression(expr.span), + true, + t_start, + t_end)) + } + _ => None }; // Note that we don't check the type of start/end satisfy any @@ -4489,7 +4439,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let range_type = match idx_type { Some(idx_type) if ty::type_is_error(idx_type) => { - ty::mk_err() + fcx.tcx().types.err } Some(idx_type) => { // Find the did from the appropriate lang item. @@ -4515,7 +4465,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ty::mk_struct(tcx, did, tcx.mk_substs(substs)) } else { tcx.sess.span_err(expr.span, "No lang item for range syntax"); - ty::mk_err() + fcx.tcx().types.err } } None => { @@ -4525,7 +4475,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, ty::mk_struct(tcx, did, tcx.mk_substs(substs)) } else { tcx.sess.span_err(expr.span, "No lang item for range syntax"); - ty::mk_err() + fcx.tcx().types.err } } }; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 47473564254..9e184db3b84 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1098,7 +1098,6 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let bounds = compute_bounds(ccx, assoc_ty, assoc_type_def.bounds.as_slice(), - &assoc_type_def.unbound, assoc_type_def.span); ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter() diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 467f34261ba..1fbfbe7eb1a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1474,7 +1474,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> { ty::ty_projection(ref data) => { let trait_ref = match data.trait_ref.clean(cx) { - TyParamBound::TraitBound(t) => t.trait_, + TyParamBound::TraitBound(t, _) => t.trait_, TyParamBound::RegionBound(_) => panic!("cleaning a trait got a region??"), }; Type::QPath { diff --git a/src/test/run-pass/trait-static-method-generic-inference.rs b/src/test/compile-fail/trait-static-method-generic-inference.rs index 4151ad6530e..651f663fc99 100644 --- a/src/test/run-pass/trait-static-method-generic-inference.rs +++ b/src/test/compile-fail/trait-static-method-generic-inference.rs @@ -8,6 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Issue #3902. We are (at least currently) unable to infer `Self` +// based on `T`, even though there is only a single impl, because of +// the possibility of associated types and other things (basically: no +// constraints on `Self` here at all). + mod base { pub trait HasNew<T> { fn new() -> T; @@ -22,19 +27,11 @@ mod base { Foo { dummy: () } } } - - pub struct Bar { - dummy: (), - } - - impl HasNew<Bar> for Bar { - fn new() -> Bar { - Bar { dummy: () } - } - } } -pub fn main() { +pub fn foo() { let _f: base::Foo = base::HasNew::new(); - let _b: base::Bar = base::HasNew::new(); + //~^ ERROR type annotations required } + +fn main() { } |
