diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs index a9dfc6ea651..118b23cf987 100644 --- a/src/librustc_mir/build/expr/as_lvalue.rs +++ b/src/librustc_mir/build/expr/as_lvalue.rs @@ -96,6 +96,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::LogicalOp { .. } | ExprKind::Box { .. } | ExprKind::Cast { .. } | + ExprKind::Use { .. } | ExprKind::NeverToAny { .. } | ExprKind::ReifyFnPointer { .. } | ExprKind::UnsafeFnPointer { .. } | diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 2123235ddc1..9b7f3468c19 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -115,6 +115,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let source = unpack!(block = this.as_operand(block, source)); block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty)) } + ExprKind::Use { source } => { + let source = unpack!(block = this.as_operand(block, source)); + block.and(Rvalue::Use(source)) + } ExprKind::ReifyFnPointer { source } => { let source = unpack!(block = this.as_operand(block, source)); block.and(Rvalue::Cast(CastKind::ReifyFnPointer, source, expr.ty)) diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index c19ea0f445a..9671f80f48b 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -68,6 +68,7 @@ impl Category { ExprKind::Binary { .. } | ExprKind::Box { .. } | ExprKind::Cast { .. } | + ExprKind::Use { .. } | ExprKind::ReifyFnPointer { .. } | ExprKind::UnsafeFnPointer { .. } | ExprKind::Unsize { .. } | diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index e5930f5a62d..58265b5b0d3 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -249,6 +249,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Binary { .. } | ExprKind::Box { .. } | ExprKind::Cast { .. } | + ExprKind::Use { .. } | ExprKind::ReifyFnPointer { .. } | ExprKind::UnsafeFnPointer { .. } | ExprKind::Unsize { .. } | diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index a6c5cd1eeea..f23c9d3caf0 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -600,8 +600,8 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // Check to see if this cast is a "coercion cast", where the cast is actually done // using a coercion (or is a no-op). if let Some(&TyCastKind::CoercionCast) = cx.tcx.cast_kinds.borrow().get(&source.id) { - // Skip the actual cast itexpr, as it's now a no-op. - return source.make_mirror(cx); + // Convert the lexpr to a vexpr. + ExprKind::Use { source: source.to_ref() } } else { ExprKind::Cast { source: source.to_ref() } } diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 353f2433353..59137e2bcd7 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -139,6 +139,9 @@ pub enum ExprKind<'tcx> { Cast { source: ExprRef<'tcx>, }, + Use { + source: ExprRef<'tcx>, + }, // Use a lexpr to get a vexpr. NeverToAny { source: ExprRef<'tcx>, }, diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 446042b839a..d80ed5e27cc 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -308,7 +308,16 @@ pub fn compare_scalar_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, _ => bug!("compare_scalar_types: must be a comparison operator"), } } - ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyBool | ty::TyUint(_) | ty::TyChar => { + ty::TyBool => { + // FIXME(#36856) -- using `from_immediate` forces these booleans into `i8`, + // which works around some LLVM bugs + ICmp(bcx, + bin_op_to_icmp_predicate(op, false), + from_immediate(bcx, lhs), + from_immediate(bcx, rhs), + debug_loc) + } + ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyUint(_) | ty::TyChar => { ICmp(bcx, bin_op_to_icmp_predicate(op, false), lhs, diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index e81bca3c171..722089cd50c 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -23,7 +23,7 @@ use rustc::hir; use std::ops::Deref; -struct ConfirmContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a>{ +struct ConfirmContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, span: Span, self_expr: &'gcx hir::Expr, @@ -55,8 +55,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { unadjusted_self_ty: Ty<'tcx>, pick: probe::Pick<'tcx>, supplied_method_types: Vec>) - -> ty::MethodCallee<'tcx> - { + -> ty::MethodCallee<'tcx> { debug!("confirm(unadjusted_self_ty={:?}, pick={:?}, supplied_method_types={:?})", unadjusted_self_ty, pick, @@ -72,17 +71,20 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { span: Span, self_expr: &'gcx hir::Expr, call_expr: &'gcx hir::Expr) - -> ConfirmContext<'a, 'gcx, 'tcx> - { - ConfirmContext { fcx: fcx, span: span, self_expr: self_expr, call_expr: call_expr } + -> ConfirmContext<'a, 'gcx, 'tcx> { + ConfirmContext { + fcx: fcx, + span: span, + self_expr: self_expr, + call_expr: call_expr, + } } fn confirm(&mut self, unadjusted_self_ty: Ty<'tcx>, pick: probe::Pick<'tcx>, supplied_method_types: Vec>) - -> ty::MethodCallee<'tcx> - { + -> ty::MethodCallee<'tcx> { // Adjust the self expression the user provided and obtain the adjusted type. let self_ty = self.adjust_self_ty(unadjusted_self_ty, &pick); @@ -91,18 +93,13 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // Create substitutions for the method's type parameters. let rcvr_substs = self.fresh_receiver_substs(self_ty, &pick); - let all_substs = - self.instantiate_method_substs( - &pick, - supplied_method_types, - rcvr_substs); + let all_substs = self.instantiate_method_substs(&pick, supplied_method_types, rcvr_substs); debug!("all_substs={:?}", all_substs); // Create the final signature for the method, replacing late-bound regions. - let InstantiatedMethodSig { - method_sig, method_predicates - } = self.instantiate_method_sig(&pick, all_substs); + let InstantiatedMethodSig { method_sig, method_predicates } = + self.instantiate_method_sig(&pick, all_substs); let method_self_ty = method_sig.inputs[0]; // Unify the (adjusted) self type with what the method expects. @@ -111,12 +108,13 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // Create the method type let def_id = pick.item.def_id(); let method_ty = pick.item.as_opt_method().unwrap(); - let fty = self.tcx.mk_fn_def(def_id, all_substs, + let fty = self.tcx.mk_fn_def(def_id, + all_substs, self.tcx.mk_bare_fn(ty::BareFnTy { - sig: ty::Binder(method_sig), - unsafety: method_ty.fty.unsafety, - abi: method_ty.fty.abi.clone(), - })); + sig: ty::Binder(method_sig), + unsafety: method_ty.fty.unsafety, + abi: method_ty.fty.abi.clone(), + })); // Add any trait/regions obligations specified on the method's type parameters. self.add_obligations(fty, all_substs, &method_predicates); @@ -125,7 +123,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { let callee = ty::MethodCallee { def_id: def_id, ty: fty, - substs: all_substs + substs: all_substs, }; if let Some(hir::MutMutable) = pick.autoref { @@ -141,14 +139,12 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { fn adjust_self_ty(&mut self, unadjusted_self_ty: Ty<'tcx>, pick: &probe::Pick<'tcx>) - -> Ty<'tcx> - { + -> Ty<'tcx> { let (autoref, unsize) = if let Some(mutbl) = pick.autoref { let region = self.next_region_var(infer::Autoref(self.span)); let autoref = AutoPtr(region, mutbl); - (Some(autoref), pick.unsize.map(|target| { - target.adjust_for_autoref(self.tcx, Some(autoref)) - })) + (Some(autoref), + pick.unsize.map(|target| target.adjust_for_autoref(self.tcx, Some(autoref)))) } else { // No unsizing should be performed without autoref (at // least during method dispach). This is because we @@ -168,11 +164,12 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { autoderef.finalize(LvaluePreference::NoPreference, Some(self.self_expr)); // Write out the final adjustment. - self.write_adjustment(self.self_expr.id, AdjustDerefRef(AutoDerefRef { - autoderefs: pick.autoderefs, - autoref: autoref, - unsize: unsize - })); + self.write_adjustment(self.self_expr.id, + AdjustDerefRef(AutoDerefRef { + autoderefs: pick.autoderefs, + autoref: autoref, + unsize: unsize, + })); if let Some(target) = unsize { target @@ -193,13 +190,13 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { fn fresh_receiver_substs(&mut self, self_ty: Ty<'tcx>, pick: &probe::Pick<'tcx>) - -> &'tcx Substs<'tcx> - { + -> &'tcx Substs<'tcx> { match pick.kind { probe::InherentImplPick => { let impl_def_id = pick.item.container().id(); assert!(self.tcx.impl_trait_ref(impl_def_id).is_none(), - "impl {:?} is not an inherent impl", impl_def_id); + "impl {:?} is not an inherent impl", + impl_def_id); self.impl_self_ty(self.span, impl_def_id).substs } @@ -216,10 +213,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // argument type), but those cases have already // been ruled out when we deemed the trait to be // "object safe". - let original_poly_trait_ref = - principal.with_self_ty(this.tcx, object_ty); - let upcast_poly_trait_ref = - this.upcast(original_poly_trait_ref, trait_def_id); + let original_poly_trait_ref = principal.with_self_ty(this.tcx, object_ty); + let upcast_poly_trait_ref = this.upcast(original_poly_trait_ref, trait_def_id); let upcast_trait_ref = this.replace_late_bound_regions_with_fresh_var(&upcast_poly_trait_ref); debug!("original_poly_trait_ref={:?} upcast_trait_ref={:?} target_trait={:?}", @@ -242,10 +237,9 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // the impl ([$A,$B,$C]) not the receiver type ([$C]). let impl_polytype = self.impl_self_ty(self.span, impl_def_id); let impl_trait_ref = - self.instantiate_type_scheme( - self.span, - impl_polytype.substs, - &self.tcx.impl_trait_ref(impl_def_id).unwrap()); + self.instantiate_type_scheme(self.span, + impl_polytype.substs, + &self.tcx.impl_trait_ref(impl_def_id).unwrap()); impl_trait_ref.substs } @@ -268,12 +262,11 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { } } - fn extract_existential_trait_ref(&mut self, - self_ty: Ty<'tcx>, - mut closure: F) -> R + fn extract_existential_trait_ref(&mut self, self_ty: Ty<'tcx>, mut closure: F) -> R where F: FnMut(&mut ConfirmContext<'a, 'gcx, 'tcx>, Ty<'tcx>, - ty::PolyExistentialTraitRef<'tcx>) -> R, + ty::PolyExistentialTraitRef<'tcx>) + -> R { // If we specified that this is an object method, then the // self-type ought to be something that can be dereferenced to @@ -281,7 +274,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // etc). // FIXME: this feels, like, super dubious - self.fcx.autoderef(self.span, self_ty) + self.fcx + .autoderef(self.span, self_ty) .filter_map(|(ty, _)| { match ty.sty { ty::TyTrait(ref data) => Some(closure(self, ty, data.principal)), @@ -290,10 +284,9 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { }) .next() .unwrap_or_else(|| { - span_bug!( - self.span, - "self-type `{}` for ObjectPick never dereferenced to an object", - self_ty) + span_bug!(self.span, + "self-type `{}` for ObjectPick never dereferenced to an object", + self_ty) }) } @@ -301,8 +294,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { pick: &probe::Pick<'tcx>, mut supplied_method_types: Vec>, substs: &Substs<'tcx>) - -> &'tcx Substs<'tcx> - { + -> &'tcx Substs<'tcx> { // Determine the values for the generic parameters of the method. // If they were not explicitly supplied, just construct fresh // variables. @@ -312,23 +304,24 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { if num_supplied_types > 0 && num_supplied_types != num_method_types { if num_method_types == 0 { - struct_span_err!(self.tcx.sess, self.span, E0035, + struct_span_err!(self.tcx.sess, + self.span, + E0035, "does not take type parameters") .span_label(self.span, &"called with unneeded type parameters") .emit(); } else { - struct_span_err!(self.tcx.sess, self.span, E0036, - "incorrect number of type parameters given for this method: \ - expected {}, found {}", - num_method_types, num_supplied_types) + struct_span_err!(self.tcx.sess, + self.span, + E0036, + "incorrect number of type parameters given for this method: \ + expected {}, found {}", + num_method_types, + num_supplied_types) .span_label(self.span, &format!("Passed {} type argument{}, expected {}", num_supplied_types, - if num_supplied_types != 1 { - "s" - } else { - "" - }, + if num_supplied_types != 1 { "s" } else { "" }, num_method_types)) .emit(); } @@ -340,14 +333,17 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // // FIXME -- permit users to manually specify lifetimes let supplied_start = substs.params().len() + method.generics.regions.len(); - Substs::for_item(self.tcx, method.def_id, |def, _| { + Substs::for_item(self.tcx, + method.def_id, + |def, _| { let i = def.index as usize; if i < substs.params().len() { substs.region_at(i) } else { self.region_var_for_def(self.span, def) } - }, |def, cur_substs| { + }, + |def, cur_substs| { let i = def.index as usize; if i < substs.params().len() { substs.type_at(i) @@ -359,21 +355,17 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { }) } - fn unify_receivers(&mut self, - self_ty: Ty<'tcx>, - method_self_ty: Ty<'tcx>) - { - match self.sub_types(false, TypeOrigin::Misc(self.span), - self_ty, method_self_ty) { + fn unify_receivers(&mut self, self_ty: Ty<'tcx>, method_self_ty: Ty<'tcx>) { + match self.sub_types(false, TypeOrigin::Misc(self.span), self_ty, method_self_ty) { Ok(InferOk { obligations, .. }) => { // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); } Err(_) => { - span_bug!( - self.span, - "{} was a subtype of {} but now is not?", - self_ty, method_self_ty); + span_bug!(self.span, + "{} was a subtype of {} but now is not?", + self_ty, + method_self_ty); } } } @@ -384,8 +376,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { fn instantiate_method_sig(&mut self, pick: &probe::Pick<'tcx>, all_substs: &'tcx Substs<'tcx>) - -> InstantiatedMethodSig<'tcx> - { + -> InstantiatedMethodSig<'tcx> { debug!("instantiate_method_sig(pick={:?}, all_substs={:?})", pick, all_substs); @@ -393,13 +384,14 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // Instantiate the bounds on the method with the // type/early-bound-regions substitutions performed. There can // be no late-bound regions appearing here. - let method_predicates = pick.item.as_opt_method().unwrap() - .predicates.instantiate(self.tcx, all_substs); - let method_predicates = self.normalize_associated_types_in(self.span, - &method_predicates); + let method_predicates = pick.item + .as_opt_method() + .unwrap() + .predicates + .instantiate(self.tcx, all_substs); + let method_predicates = self.normalize_associated_types_in(self.span, &method_predicates); - debug!("method_predicates after subst = {:?}", - method_predicates); + debug!("method_predicates after subst = {:?}", method_predicates); // Instantiate late-bound regions and substitute the trait // parameters into the method type to get the actual method type. @@ -407,14 +399,16 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // NB: Instantiate late-bound regions first so that // `instantiate_type_scheme` can normalize associated types that // may reference those regions. - let method_sig = self.replace_late_bound_regions_with_fresh_var( - &pick.item.as_opt_method().unwrap().fty.sig); + let method_sig = self.replace_late_bound_regions_with_fresh_var(&pick.item + .as_opt_method() + .unwrap() + .fty + .sig); debug!("late-bound lifetimes from method instantiated, method_sig={:?}", method_sig); let method_sig = self.instantiate_type_scheme(self.span, all_substs, &method_sig); - debug!("type scheme substituted, method_sig={:?}", - method_sig); + debug!("type scheme substituted, method_sig={:?}", method_sig); InstantiatedMethodSig { method_sig: method_sig, @@ -431,9 +425,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { all_substs, method_predicates); - self.add_obligations_for_parameters( - traits::ObligationCause::misc(self.span, self.body_id), - method_predicates); + self.add_obligations_for_parameters(traits::ObligationCause::misc(self.span, self.body_id), + method_predicates); // this is a projection from a trait reference, so we have to // make sure that the trait reference inputs are well-formed. @@ -472,21 +465,24 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { for (i, &expr) in exprs.iter().rev().enumerate() { // Count autoderefs. let autoderef_count = match self.tables - .borrow() - .adjustments - .get(&expr.id) { + .borrow() + .adjustments + .get(&expr.id) { Some(&AdjustDerefRef(ref adj)) => adj.autoderefs, Some(_) | None => 0, }; debug!("convert_lvalue_derefs_to_mutable: i={} expr={:?} \ autoderef_count={}", - i, expr, autoderef_count); + i, + expr, + autoderef_count); if autoderef_count > 0 { let mut autoderef = self.autoderef(expr.span, self.node_ty(expr.id)); autoderef.nth(autoderef_count).unwrap_or_else(|| { - span_bug!(expr.span, "expr was deref-able {} times but now isn't?", + span_bug!(expr.span, + "expr was deref-able {} times but now isn't?", autoderef_count); }); autoderef.finalize(PreferMutLvalue, Some(expr)); @@ -508,29 +504,30 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // (ab)use the normal type checking paths. let adj = self.tables.borrow().adjustments.get(&base_expr.id).cloned(); let (autoderefs, unsize) = match adj { - Some(AdjustDerefRef(adr)) => match adr.autoref { - None => { - assert!(adr.unsize.is_none()); - (adr.autoderefs, None) + Some(AdjustDerefRef(adr)) => { + match adr.autoref { + None => { + assert!(adr.unsize.is_none()); + (adr.autoderefs, None) + } + Some(AutoPtr(..)) => { + (adr.autoderefs, + adr.unsize.map(|target| { + target.builtin_deref(false, NoPreference) + .expect("fixup: AutoPtr is not &T") + .ty + })) + } + Some(_) => { + span_bug!(base_expr.span, + "unexpected adjustment autoref {:?}", + adr); + } } - Some(AutoPtr(..)) => { - (adr.autoderefs, adr.unsize.map(|target| { - target.builtin_deref(false, NoPreference) - .expect("fixup: AutoPtr is not &T").ty - })) - } - Some(_) => { - span_bug!( - base_expr.span, - "unexpected adjustment autoref {:?}", - adr); - } - }, + } None => (0, None), Some(_) => { - span_bug!( - base_expr.span, - "unexpected adjustment type"); + span_bug!(base_expr.span, "unexpected adjustment type"); } }; @@ -538,23 +535,23 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { (target, true) } else { (self.adjust_expr_ty(base_expr, - Some(&AdjustDerefRef(AutoDerefRef { - autoderefs: autoderefs, - autoref: None, - unsize: None - }))), false) + Some(&AdjustDerefRef(AutoDerefRef { + autoderefs: autoderefs, + autoref: None, + unsize: None, + }))), + false) }; let index_expr_ty = self.node_ty(index_expr.id); - let result = self.try_index_step( - ty::MethodCall::expr(expr.id), - expr, - &base_expr, - adjusted_base_ty, - autoderefs, - unsize, - PreferMutLvalue, - index_expr_ty); + let result = self.try_index_step(ty::MethodCall::expr(expr.id), + expr, + &base_expr, + adjusted_base_ty, + autoderefs, + unsize, + PreferMutLvalue, + index_expr_ty); if let Some((input_ty, return_ty)) = result { self.demand_suptype(index_expr.span, input_ty, index_expr_ty); @@ -569,9 +566,9 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { let method_call = ty::MethodCall::expr(expr.id); if self.tables.borrow().method_map.contains_key(&method_call) { let method = self.try_overloaded_deref(expr.span, - Some(&base_expr), - self.node_ty(base_expr.id), - PreferMutLvalue); + Some(&base_expr), + self.node_ty(base_expr.id), + PreferMutLvalue); let method = method.expect("re-trying deref failed"); self.tables.borrow_mut().method_map.insert(method_call, method); } @@ -597,28 +594,27 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { fn upcast(&mut self, source_trait_ref: ty::PolyTraitRef<'tcx>, target_trait_def_id: DefId) - -> ty::PolyTraitRef<'tcx> - { - let upcast_trait_refs = self.tcx.upcast_choices(source_trait_ref.clone(), - target_trait_def_id); + -> ty::PolyTraitRef<'tcx> { + let upcast_trait_refs = self.tcx + .upcast_choices(source_trait_ref.clone(), target_trait_def_id); // must be exactly one trait ref or we'd get an ambig error etc if upcast_trait_refs.len() != 1 { - span_bug!( - self.span, - "cannot uniquely upcast `{:?}` to `{:?}`: `{:?}`", - source_trait_ref, - target_trait_def_id, - upcast_trait_refs); + span_bug!(self.span, + "cannot uniquely upcast `{:?}` to `{:?}`: `{:?}`", + source_trait_ref, + target_trait_def_id, + upcast_trait_refs); } upcast_trait_refs.into_iter().next().unwrap() } fn replace_late_bound_regions_with_fresh_var(&self, value: &ty::Binder) -> T - where T : TypeFoldable<'tcx> + where T: TypeFoldable<'tcx> { - self.fcx.replace_late_bound_regions_with_fresh_var( - self.span, infer::FnCall, value).0 + self.fcx + .replace_late_bound_regions_with_fresh_var(self.span, infer::FnCall, value) + .0 } } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 73caf79c9f8..f084b85a45f 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -41,7 +41,8 @@ pub enum MethodError<'tcx> { Ambiguity(Vec), // Using a `Fn`/`FnMut`/etc method on a raw closure type before we have inferred its kind. - ClosureAmbiguity(/* DefId of fn trait */ DefId), + ClosureAmbiguity(// DefId of fn trait + DefId), // Found an applicable method, but it is not visible. PrivateMatch(Def), @@ -53,19 +54,20 @@ pub struct NoMatchData<'tcx> { pub static_candidates: Vec, pub unsatisfied_predicates: Vec>, pub out_of_scope_traits: Vec, - pub mode: probe::Mode + pub mode: probe::Mode, } impl<'tcx> NoMatchData<'tcx> { pub fn new(static_candidates: Vec, unsatisfied_predicates: Vec>, out_of_scope_traits: Vec, - mode: probe::Mode) -> Self { + mode: probe::Mode) + -> Self { NoMatchData { static_candidates: static_candidates, unsatisfied_predicates: unsatisfied_predicates, out_of_scope_traits: out_of_scope_traits, - mode: mode + mode: mode, } } } @@ -75,7 +77,8 @@ impl<'tcx> NoMatchData<'tcx> { #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum CandidateSource { ImplSource(DefId), - TraitSource(/* trait id */ DefId), + TraitSource(// trait id + DefId), } impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { @@ -86,8 +89,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self_ty: ty::Ty<'tcx>, call_expr_id: ast::NodeId, allow_private: bool) - -> bool - { + -> bool { let mode = probe::Mode::MethodCall; match self.probe_method(span, mode, method_name, self_ty, call_expr_id) { Ok(..) => true, @@ -119,8 +121,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { supplied_method_types: Vec>, call_expr: &'gcx hir::Expr, self_expr: &'gcx hir::Expr) - -> Result, MethodError<'tcx>> - { + -> Result, MethodError<'tcx>> { debug!("lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})", method_name, self_ty, @@ -135,7 +136,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.tcx.used_trait_imports.borrow_mut().insert(import_id); } - Ok(self.confirm_method(span, self_expr, call_expr, self_ty, pick, supplied_method_types)) + Ok(self.confirm_method(span, + self_expr, + call_expr, + self_ty, + pick, + supplied_method_types)) } pub fn lookup_method_in_trait(&self, @@ -145,10 +151,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { trait_def_id: DefId, self_ty: ty::Ty<'tcx>, opt_input_types: Option>>) - -> Option> - { - self.lookup_method_in_trait_adjusted(span, self_expr, m_name, trait_def_id, - 0, false, self_ty, opt_input_types) + -> Option> { + self.lookup_method_in_trait_adjusted(span, + self_expr, + m_name, + trait_def_id, + 0, + false, + self_ty, + opt_input_types) } /// `lookup_in_trait_adjusted` is used for overloaded operators. @@ -171,8 +182,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { unsize: bool, self_ty: ty::Ty<'tcx>, opt_input_types: Option>>) - -> Option> - { + -> Option> { debug!("lookup_in_trait_adjusted(self_ty={:?}, self_expr={:?}, \ m_name={}, trait_def_id={:?})", self_ty, @@ -188,9 +198,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { assert!(trait_def.generics.regions.is_empty()); // Construct a trait-reference `self_ty : Trait` - let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| { - self.region_var_for_def(span, def) - }, |def, substs| { + let substs = Substs::for_item(self.tcx, + trait_def_id, + |def, _| self.region_var_for_def(span, def), + |def, substs| { if def.index == 0 { self_ty } else if let Some(ref input_types) = opt_input_types { @@ -204,9 +215,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Construct an obligation let poly_trait_ref = trait_ref.to_poly_trait_ref(); - let obligation = traits::Obligation::misc(span, - self.body_id, - poly_trait_ref.to_predicate()); + let obligation = + traits::Obligation::misc(span, self.body_id, poly_trait_ref.to_predicate()); // Now we want to know if this can be matched let mut selcx = traits::SelectionContext::new(self); @@ -224,7 +234,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { assert_eq!(method_ty.generics.regions.len(), 0); debug!("lookup_in_trait_adjusted: method_item={:?} method_ty={:?}", - method_item, method_ty); + method_item, + method_ty); // Instantiate late-bound regions and substitute the trait // parameters into the method type to get the actual method type. @@ -232,18 +243,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // NB: Instantiate late-bound regions first so that // `instantiate_type_scheme` can normalize associated types that // may reference those regions. - let fn_sig = self.replace_late_bound_regions_with_fresh_var(span, - infer::FnCall, - &method_ty.fty.sig).0; + let fn_sig = + self.replace_late_bound_regions_with_fresh_var(span, infer::FnCall, &method_ty.fty.sig) + .0; let fn_sig = self.instantiate_type_scheme(span, trait_ref.substs, &fn_sig); let transformed_self_ty = fn_sig.inputs[0]; let def_id = method_item.def_id(); - let fty = tcx.mk_fn_def(def_id, trait_ref.substs, + let fty = tcx.mk_fn_def(def_id, + trait_ref.substs, tcx.mk_bare_fn(ty::BareFnTy { - sig: ty::Binder(fn_sig), - unsafety: method_ty.fty.unsafety, - abi: method_ty.fty.abi.clone(), - })); + sig: ty::Binder(fn_sig), + unsafety: method_ty.fty.unsafety, + abi: method_ty.fty.abi.clone(), + })); debug!("lookup_in_trait_adjusted: matched method fty={:?} obligation={:?}", fty, @@ -259,9 +271,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // any late-bound regions appearing in its bounds. let method_bounds = self.instantiate_bounds(span, trait_ref.substs, &method_ty.predicates); assert!(!method_bounds.has_escaping_regions()); - self.add_obligations_for_parameters( - traits::ObligationCause::misc(span, self.body_id), - &method_bounds); + self.add_obligations_for_parameters(traits::ObligationCause::misc(span, self.body_id), + &method_bounds); // Also register an obligation for the method type being well-formed. self.register_wf_obligation(fty, span, traits::MiscObligation); @@ -273,12 +284,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Insert any adjustments needed (always an autoref of some mutability). match self_expr { - None => { } + None => {} Some(self_expr) => { debug!("lookup_in_trait_adjusted: inserting adjustment if needed \ (self-id={}, autoderefs={}, unsize={}, explicit_self={:?})", - self_expr.id, autoderefs, unsize, + self_expr.id, + autoderefs, + unsize, method_ty.explicit_self); match method_ty.explicit_self { @@ -294,31 +307,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match transformed_self_ty.sty { ty::TyRef(region, ty::TypeAndMut { mutbl, ty: _ }) => { self.write_adjustment(self_expr.id, - AdjustDerefRef(AutoDerefRef { - autoderefs: autoderefs, - autoref: Some(AutoPtr(region, mutbl)), - unsize: if unsize { - Some(transformed_self_ty) - } else { - None - } - })); + AdjustDerefRef(AutoDerefRef { + autoderefs: autoderefs, + autoref: Some(AutoPtr(region, mutbl)), + unsize: if unsize { + Some(transformed_self_ty) + } else { + None + }, + })); } _ => { - span_bug!( - span, - "trait method is &self but first arg is: {}", - transformed_self_ty); + span_bug!(span, + "trait method is &self but first arg is: {}", + transformed_self_ty); } } } _ => { - span_bug!( - span, - "unexpected explicit self type in operator method: {:?}", - method_ty.explicit_self); + span_bug!(span, + "unexpected explicit self type in operator method: {:?}", + method_ty.explicit_self); } } } @@ -327,7 +338,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let callee = ty::MethodCallee { def_id: def_id, ty: fty, - substs: trait_ref.substs + substs: trait_ref.substs, }; debug!("callee = {:?}", callee); @@ -340,8 +351,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { method_name: ast::Name, self_ty: ty::Ty<'tcx>, expr_id: ast::NodeId) - -> Result> - { + -> Result> { let mode = probe::Mode::Path; let pick = self.probe_method(span, mode, method_name, self_ty, expr_id)?; @@ -364,9 +374,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn impl_or_trait_item(&self, def_id: DefId, item_name: ast::Name) - -> Option> - { - self.tcx.impl_or_trait_items(def_id) + -> Option> { + self.tcx + .impl_or_trait_items(def_id) .iter() .map(|&did| self.tcx.impl_or_trait_item(did)) .find(|m| m.name() == item_name) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 9fba9bcb757..43837de2f34 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -13,7 +13,7 @@ use super::NoMatchData; use super::{CandidateSource, ImplSource, TraitSource}; use super::suggest; -use check::{FnCtxt}; +use check::FnCtxt; use hir::def_id::DefId; use hir::def::Def; use rustc::ty::subst::{Subst, Substs}; @@ -31,7 +31,7 @@ use std::rc::Rc; use self::CandidateKind::*; pub use self::PickKind::*; -struct ProbeContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { +struct ProbeContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, span: Span, mode: Mode, @@ -52,7 +52,7 @@ struct ProbeContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used /// for error reporting - unsatisfied_predicates: Vec> + unsatisfied_predicates: Vec>, } impl<'a, 'gcx, 'tcx> Deref for ProbeContext<'a, 'gcx, 'tcx> { @@ -66,7 +66,7 @@ impl<'a, 'gcx, 'tcx> Deref for ProbeContext<'a, 'gcx, 'tcx> { struct CandidateStep<'tcx> { self_ty: Ty<'tcx>, autoderefs: usize, - unsize: bool + unsize: bool, } #[derive(Debug)] @@ -80,12 +80,17 @@ struct Candidate<'tcx> { #[derive(Debug)] enum CandidateKind<'tcx> { InherentImplCandidate(&'tcx Substs<'tcx>, - /* Normalize obligations */ Vec>), - ExtensionImplCandidate(/* Impl */ DefId, &'tcx Substs<'tcx>, - /* Normalize obligations */ Vec>), + // Normalize obligations + Vec>), + ExtensionImplCandidate(// Impl + DefId, + &'tcx Substs<'tcx>, + // Normalize obligations + Vec>), ObjectCandidate, TraitCandidate, - WhereClauseCandidate(/* Trait */ ty::PolyTraitRef<'tcx>), + WhereClauseCandidate(// Trait + ty::PolyTraitRef<'tcx>), } #[derive(Debug)] @@ -115,10 +120,12 @@ pub struct Pick<'tcx> { #[derive(Clone,Debug)] pub enum PickKind<'tcx> { InherentImplPick, - ExtensionImplPick(/* Impl */ DefId), + ExtensionImplPick(// Impl + DefId), ObjectPick, TraitPick, - WhereClausePick(/* Trait */ ty::PolyTraitRef<'tcx>), + WhereClausePick(// Trait + ty::PolyTraitRef<'tcx>), } pub type PickResult<'tcx> = Result, MethodError<'tcx>>; @@ -132,7 +139,7 @@ pub enum Mode { // An expression of the form `Type::item` or `::item`. // No autoderefs are performed, lookup is done based on the type each // implementation is for, and static methods are included. - Path + Path, } impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { @@ -142,8 +149,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { item_name: ast::Name, self_ty: Ty<'tcx>, scope_expr_id: ast::NodeId) - -> PickResult<'tcx> - { + -> PickResult<'tcx> { debug!("probe(self_ty={:?}, item_name={}, scope_expr_id={})", self_ty, item_name, @@ -159,31 +165,38 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let steps = if mode == Mode::MethodCall { match self.create_steps(span, self_ty) { Some(steps) => steps, - None =>return Err(MethodError::NoMatch(NoMatchData::new(Vec::new(), Vec::new(), - Vec::new(), mode))), + None => { + return Err(MethodError::NoMatch(NoMatchData::new(Vec::new(), + Vec::new(), + Vec::new(), + mode))) + } } } else { vec![CandidateStep { - self_ty: self_ty, - autoderefs: 0, - unsize: false - }] + self_ty: self_ty, + autoderefs: 0, + unsize: false, + }] }; // Create a list of simplified self types, if we can. let mut simplified_steps = Vec::new(); for step in &steps { match ty::fast_reject::simplify_type(self.tcx, step.self_ty, true) { - None => { break; } - Some(simplified_type) => { simplified_steps.push(simplified_type); } + None => { + break; + } + Some(simplified_type) => { + simplified_steps.push(simplified_type); + } } } - let opt_simplified_steps = - if simplified_steps.len() < steps.len() { - None // failed to convert at least one of the steps - } else { - Some(simplified_steps) - }; + let opt_simplified_steps = if simplified_steps.len() < steps.len() { + None // failed to convert at least one of the steps + } else { + Some(simplified_steps) + }; debug!("ProbeContext: steps for self_ty={:?} are {:?}", self_ty, @@ -192,31 +205,27 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // this creates one big transaction so that all type variables etc // that we create during the probe process are removed later self.probe(|_| { - let mut probe_cx = ProbeContext::new(self, - span, - mode, - item_name, - steps, - opt_simplified_steps); + let mut probe_cx = + ProbeContext::new(self, span, mode, item_name, steps, opt_simplified_steps); probe_cx.assemble_inherent_candidates(); probe_cx.assemble_extension_candidates_for_traits_in_scope(scope_expr_id)?; probe_cx.pick() }) } - fn create_steps(&self, - span: Span, - self_ty: Ty<'tcx>) - -> Option>> - { + fn create_steps(&self, span: Span, self_ty: Ty<'tcx>) -> Option>> { // FIXME: we don't need to create the entire steps in one pass let mut autoderef = self.autoderef(span, self_ty); - let mut steps: Vec<_> = autoderef.by_ref().map(|(ty, d)| CandidateStep { - self_ty: ty, - autoderefs: d, - unsize: false - }).collect(); + let mut steps: Vec<_> = autoderef.by_ref() + .map(|(ty, d)| { + CandidateStep { + self_ty: ty, + autoderefs: d, + unsize: false, + } + }) + .collect(); let final_ty = autoderef.unambiguous_final_ty(); match final_ty.sty { @@ -226,7 +235,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { steps.push(CandidateStep { self_ty: self.tcx.mk_slice(elem_ty), autoderefs: dereferences, - unsize: true + unsize: true, }); } ty::TyError => return None, @@ -246,8 +255,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { item_name: ast::Name, steps: Vec>, opt_simplified_steps: Option>) - -> ProbeContext<'a, 'gcx, 'tcx> - { + -> ProbeContext<'a, 'gcx, 'tcx> { ProbeContext { fcx: fcx, span: span, @@ -284,8 +292,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { } fn assemble_probe(&mut self, self_ty: Ty<'tcx>) { - debug!("assemble_probe: self_ty={:?}", - self_ty); + debug!("assemble_probe: self_ty={:?}", self_ty); match self_ty.sty { ty::TyTrait(box ref data) => { @@ -371,8 +378,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let lang_def_id = self.tcx.lang_items.f64_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); } - _ => { - } + _ => {} } } @@ -405,7 +411,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let item = match self.impl_or_trait_item(impl_def_id) { Some(m) => m, - None => { return; } // No method with correct name on this impl + None => { + return; + } // No method with correct name on this impl }; if !self.has_applicable_self(&item) { @@ -415,7 +423,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { if !item.vis().is_accessible_from(self.body_id, &self.tcx.map) { self.private_candidate = Some(item.def()); - return + return; } let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id); @@ -458,9 +466,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { self.elaborate_bounds(&[trait_ref], |this, new_trait_ref, item| { let new_trait_ref = this.erase_late_bound_regions(&new_trait_ref); - let xform_self_ty = this.xform_self_ty(&item, - new_trait_ref.self_ty(), - new_trait_ref.substs); + let xform_self_ty = + this.xform_self_ty(&item, new_trait_ref.self_ty(), new_trait_ref.substs); this.inherent_candidates.push(Candidate { xform_self_ty: xform_self_ty, @@ -476,8 +483,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { param_ty: ty::ParamTy) { // FIXME -- Do we want to commit to this behavior for param bounds? - let bounds: Vec<_> = - self.parameter_environment.caller_bounds + let bounds: Vec<_> = self.parameter_environment + .caller_bounds .iter() .filter_map(|predicate| { match *predicate { @@ -486,7 +493,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { ty::TyParam(ref p) if *p == param_ty => { Some(trait_predicate.to_poly_trait_ref()) } - _ => None + _ => None, } } ty::Predicate::Equate(..) | @@ -495,21 +502,15 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { ty::Predicate::WellFormed(..) | ty::Predicate::ObjectSafe(..) | ty::Predicate::ClosureKind(..) | - ty::Predicate::TypeOutlives(..) => { - None - } + ty::Predicate::TypeOutlives(..) => None, } }) .collect(); self.elaborate_bounds(&bounds, |this, poly_trait_ref, item| { - let trait_ref = - this.erase_late_bound_regions(&poly_trait_ref); + let trait_ref = this.erase_late_bound_regions(&poly_trait_ref); - let xform_self_ty = - this.xform_self_ty(&item, - trait_ref.self_ty(), - trait_ref.substs); + let xform_self_ty = this.xform_self_ty(&item, trait_ref.self_ty(), trait_ref.substs); if let Some(ref m) = item.as_opt_method() { debug!("found match: trait_ref={:?} substs={:?} m={:?}", @@ -540,16 +541,10 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // Do a search through a list of bounds, using a callback to actually // create the candidates. - fn elaborate_bounds( - &mut self, - bounds: &[ty::PolyTraitRef<'tcx>], - mut mk_cand: F, - ) where - F: for<'b> FnMut( - &mut ProbeContext<'b, 'gcx, 'tcx>, - ty::PolyTraitRef<'tcx>, - ty::ImplOrTraitItem<'tcx>, - ), + fn elaborate_bounds(&mut self, bounds: &[ty::PolyTraitRef<'tcx>], mut mk_cand: F) + where F: for<'b> FnMut(&mut ProbeContext<'b, 'gcx, 'tcx>, + ty::PolyTraitRef<'tcx>, + ty::ImplOrTraitItem<'tcx>) { debug!("elaborate_bounds(bounds={:?})", bounds); @@ -557,7 +552,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { for bound_trait_ref in traits::transitive_bounds(tcx, bounds) { let item = match self.impl_or_trait_item(bound_trait_ref.def_id()) { Some(v) => v, - None => { continue; } + None => { + continue; + } }; if !self.has_applicable_self(&item) { @@ -570,8 +567,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_extension_candidates_for_traits_in_scope(&mut self, expr_id: ast::NodeId) - -> Result<(), MethodError<'tcx>> - { + -> Result<(), MethodError<'tcx>> { let mut duplicates = FnvHashSet(); let opt_applicable_traits = self.tcx.trait_map.get(&expr_id); if let Some(applicable_traits) = opt_applicable_traits { @@ -600,20 +596,19 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_extension_candidates_for_trait(&mut self, trait_def_id: DefId) - -> Result<(), MethodError<'tcx>> - { + -> Result<(), MethodError<'tcx>> { debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id); // Check whether `trait_def_id` defines a method with suitable name: - let trait_items = - self.tcx.trait_items(trait_def_id); - let maybe_item = - trait_items.iter() - .find(|item| item.name() == self.item_name); + let trait_items = self.tcx.trait_items(trait_def_id); + let maybe_item = trait_items.iter() + .find(|item| item.name() == self.item_name); let item = match maybe_item { Some(i) => i, - None => { return Ok(()); } + None => { + return Ok(()); + } }; // Check whether `trait_def_id` defines a method with suitable name: @@ -636,8 +631,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_extension_candidates_for_trait_impls(&mut self, trait_def_id: DefId, - item: ty::ImplOrTraitItem<'tcx>) - { + item: ty::ImplOrTraitItem<'tcx>) { let trait_def = self.tcx.lookup_trait_def(trait_def_id); // FIXME(arielb1): can we use for_each_relevant_impl here? @@ -655,8 +649,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { debug!("impl_substs={:?}", impl_substs); - let impl_trait_ref = - self.tcx.impl_trait_ref(impl_def_id) + let impl_trait_ref = self.tcx.impl_trait_ref(impl_def_id) .unwrap() // we know this is a trait impl .subst(self.tcx, impl_substs); @@ -664,9 +657,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // Determine the receiver type that the method itself expects. let xform_self_ty = - self.xform_self_ty(&item, - impl_trait_ref.self_ty(), - impl_trait_ref.substs); + self.xform_self_ty(&item, impl_trait_ref.self_ty(), impl_trait_ref.substs); // Normalize the receiver. We can't use normalize_associated_types_in // as it will pollute the fcx's fulfillment context after this probe @@ -690,14 +681,18 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn impl_can_possibly_match(&self, impl_def_id: DefId) -> bool { let simplified_steps = match self.opt_simplified_steps { Some(ref simplified_steps) => simplified_steps, - None => { return true; } + None => { + return true; + } }; let impl_type = self.tcx.lookup_item_type(impl_def_id); let impl_simplified_type = match ty::fast_reject::simplify_type(self.tcx, impl_type.ty, false) { Some(simplified_type) => simplified_type, - None => { return true; } + None => { + return true; + } }; simplified_steps.contains(&impl_simplified_type) @@ -706,8 +701,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_closure_candidates(&mut self, trait_def_id: DefId, item: ty::ImplOrTraitItem<'tcx>) - -> Result<(), MethodError<'tcx>> - { + -> Result<(), MethodError<'tcx>> { // Check if this is one of the Fn,FnMut,FnOnce traits. let tcx = self.tcx; let kind = if Some(trait_def_id) == tcx.lang_items.fn_trait() { @@ -746,9 +740,10 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // for the purposes of our method lookup, we only take // receiver type into account, so we can just substitute // fresh types here to use during substitution and subtyping. - let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| { - self.region_var_for_def(self.span, def) - }, |def, substs| { + let substs = Substs::for_item(self.tcx, + trait_def_id, + |def, _| self.region_var_for_def(self.span, def), + |def, substs| { if def.index == 0 { step.self_ty } else { @@ -756,9 +751,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { } }); - let xform_self_ty = self.xform_self_ty(&item, - step.self_ty, - substs); + let xform_self_ty = self.xform_self_ty(&item, step.self_ty, substs); self.inherent_candidates.push(Candidate { xform_self_ty: xform_self_ty, item: item.clone(), @@ -772,8 +765,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_projection_candidates(&mut self, trait_def_id: DefId, - item: ty::ImplOrTraitItem<'tcx>) - { + item: ty::ImplOrTraitItem<'tcx>) { debug!("assemble_projection_candidates(\ trait_def_id={:?}, \ item={:?})", @@ -781,39 +773,35 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { item); for step in self.steps.iter() { - debug!("assemble_projection_candidates: step={:?}", - step); + debug!("assemble_projection_candidates: step={:?}", step); let (def_id, substs) = match step.self_ty.sty { - ty::TyProjection(ref data) => { - (data.trait_ref.def_id, data.trait_ref.substs) - } + ty::TyProjection(ref data) => (data.trait_ref.def_id, data.trait_ref.substs), ty::TyAnon(def_id, substs) => (def_id, substs), _ => continue, }; debug!("assemble_projection_candidates: def_id={:?} substs={:?}", - def_id, substs); + def_id, + substs); let trait_predicates = self.tcx.lookup_predicates(def_id); let bounds = trait_predicates.instantiate(self.tcx, substs); let predicates = bounds.predicates; debug!("assemble_projection_candidates: predicates={:?}", predicates); - for poly_bound in - traits::elaborate_predicates(self.tcx, predicates) + for poly_bound in traits::elaborate_predicates(self.tcx, predicates) .filter_map(|p| p.to_opt_poly_trait_ref()) - .filter(|b| b.def_id() == trait_def_id) - { + .filter(|b| b.def_id() == trait_def_id) { let bound = self.erase_late_bound_regions(&poly_bound); debug!("assemble_projection_candidates: def_id={:?} substs={:?} bound={:?}", - def_id, substs, bound); + def_id, + substs, + bound); if self.can_equate(&step.self_ty, &bound.self_ty()).is_ok() { - let xform_self_ty = self.xform_self_ty(&item, - bound.self_ty(), - bound.substs); + let xform_self_ty = self.xform_self_ty(&item, bound.self_ty(), bound.substs); debug!("assemble_projection_candidates: bound={:?} xform_self_ty={:?}", bound, @@ -832,20 +820,16 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_where_clause_candidates(&mut self, trait_def_id: DefId, - item: ty::ImplOrTraitItem<'tcx>) - { + item: ty::ImplOrTraitItem<'tcx>) { debug!("assemble_where_clause_candidates(trait_def_id={:?})", trait_def_id); let caller_predicates = self.parameter_environment.caller_bounds.clone(); for poly_bound in traits::elaborate_predicates(self.tcx, caller_predicates) - .filter_map(|p| p.to_opt_poly_trait_ref()) - .filter(|b| b.def_id() == trait_def_id) - { + .filter_map(|p| p.to_opt_poly_trait_ref()) + .filter(|b| b.def_id() == trait_def_id) { let bound = self.erase_late_bound_regions(&poly_bound); - let xform_self_ty = self.xform_self_ty(&item, - bound.self_ty(), - bound.substs); + let xform_self_ty = self.xform_self_ty(&item, bound.self_ty(), bound.substs); debug!("assemble_where_clause_candidates: bound={:?} xform_self_ty={:?}", bound, @@ -882,19 +866,24 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let out_of_scope_traits = match self.pick_core() { Some(Ok(p)) => vec![p.item.container().id()], - Some(Err(MethodError::Ambiguity(v))) => v.into_iter().map(|source| { - match source { - TraitSource(id) => id, - ImplSource(impl_id) => { - match tcx.trait_id_of_impl(impl_id) { - Some(id) => id, - None => - span_bug!(span, - "found inherent method when looking at traits") + Some(Err(MethodError::Ambiguity(v))) => { + v.into_iter() + .map(|source| { + match source { + TraitSource(id) => id, + ImplSource(impl_id) => { + match tcx.trait_id_of_impl(impl_id) { + Some(id) => id, + None => { + span_bug!(span, + "found inherent method when looking at traits") + } + } + } } - } - } - }).collect(), + }) + .collect() + } Some(Err(MethodError::NoMatch(NoMatchData { out_of_scope_traits: others, .. }))) => { assert!(others.is_empty()); vec![] @@ -910,8 +899,10 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { return Err(MethodError::PrivateMatch(def)); } - Err(MethodError::NoMatch(NoMatchData::new(static_candidates, unsatisfied_predicates, - out_of_scope_traits, self.mode))) + Err(MethodError::NoMatch(NoMatchData::new(static_candidates, + unsatisfied_predicates, + out_of_scope_traits, + self.mode))) } fn pick_core(&mut self) -> Option> { @@ -935,41 +926,35 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { self.pick_autorefd_method(step) } - fn pick_by_value_method(&mut self, - step: &CandidateStep<'tcx>) - -> Option> - { - /*! - * For each type `T` in the step list, this attempts to find a - * method where the (transformed) self type is exactly `T`. We - * do however do one transformation on the adjustment: if we - * are passing a region pointer in, we will potentially - * *reborrow* it to a shorter lifetime. This allows us to - * transparently pass `&mut` pointers, in particular, without - * consuming them for their entire lifetime. - */ + fn pick_by_value_method(&mut self, step: &CandidateStep<'tcx>) -> Option> { + //! For each type `T` in the step list, this attempts to find a + //! method where the (transformed) self type is exactly `T`. We + //! do however do one transformation on the adjustment: if we + //! are passing a region pointer in, we will potentially + //! *reborrow* it to a shorter lifetime. This allows us to + //! transparently pass `&mut` pointers, in particular, without + //! consuming them for their entire lifetime. if step.unsize { return None; } - self.pick_method(step.self_ty).map(|r| r.map(|mut pick| { - pick.autoderefs = step.autoderefs; + self.pick_method(step.self_ty).map(|r| { + r.map(|mut pick| { + pick.autoderefs = step.autoderefs; - // Insert a `&*` or `&mut *` if this is a reference type: - if let ty::TyRef(_, mt) = step.self_ty.sty { - pick.autoderefs += 1; - pick.autoref = Some(mt.mutbl); - } + // Insert a `&*` or `&mut *` if this is a reference type: + if let ty::TyRef(_, mt) = step.self_ty.sty { + pick.autoderefs += 1; + pick.autoref = Some(mt.mutbl); + } - pick - })) + pick + }) + }) } - fn pick_autorefd_method(&mut self, - step: &CandidateStep<'tcx>) - -> Option> - { + fn pick_autorefd_method(&mut self, step: &CandidateStep<'tcx>) -> Option> { let tcx = self.tcx; // In general, during probing we erase regions. See @@ -977,22 +962,28 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let region = tcx.mk_region(ty::ReErased); // Search through mutabilities in order to find one where pick works: - [hir::MutImmutable, hir::MutMutable].iter().filter_map(|&m| { - let autoref_ty = tcx.mk_ref(region, ty::TypeAndMut { - ty: step.self_ty, - mutbl: m - }); - self.pick_method(autoref_ty).map(|r| r.map(|mut pick| { - pick.autoderefs = step.autoderefs; - pick.autoref = Some(m); - pick.unsize = if step.unsize { - Some(step.self_ty) - } else { - None - }; - pick - })) - }).nth(0) + [hir::MutImmutable, hir::MutMutable] + .iter() + .filter_map(|&m| { + let autoref_ty = tcx.mk_ref(region, + ty::TypeAndMut { + ty: step.self_ty, + mutbl: m, + }); + self.pick_method(autoref_ty).map(|r| { + r.map(|mut pick| { + pick.autoderefs = step.autoderefs; + pick.autoref = Some(m); + pick.unsize = if step.unsize { + Some(step.self_ty) + } else { + None + }; + pick + }) + }) + }) + .nth(0) } fn pick_method(&mut self, self_ty: Ty<'tcx>) -> Option> { @@ -1008,7 +999,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { } debug!("searching extension candidates"); - let res = self.consider_candidates(self_ty, &self.extension_candidates, + let res = self.consider_candidates(self_ty, + &self.extension_candidates, &mut possibly_unsatisfied_predicates); if let None = res { self.unsatisfied_predicates.extend(possibly_unsatisfied_predicates); @@ -1021,18 +1013,18 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { probes: &[Candidate<'tcx>], possibly_unsatisfied_predicates: &mut Vec>) -> Option> { - let mut applicable_candidates: Vec<_> = - probes.iter() - .filter(|&probe| self.consider_probe(self_ty, - probe,possibly_unsatisfied_predicates)) - .collect(); + let mut applicable_candidates: Vec<_> = probes.iter() + .filter(|&probe| self.consider_probe(self_ty, probe, possibly_unsatisfied_predicates)) + .collect(); debug!("applicable_candidates: {:?}", applicable_candidates); if applicable_candidates.len() > 1 { match self.collapse_candidates_to_trait_pick(&applicable_candidates[..]) { - Some(pick) => { return Some(Ok(pick)); } - None => { } + Some(pick) => { + return Some(Ok(pick)); + } + None => {} } } @@ -1041,21 +1033,22 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { return Some(Err(MethodError::Ambiguity(sources))); } - applicable_candidates.pop().map(|probe| { - Ok(probe.to_unadjusted_pick()) - }) + applicable_candidates.pop().map(|probe| Ok(probe.to_unadjusted_pick())) } - fn consider_probe(&self, self_ty: Ty<'tcx>, probe: &Candidate<'tcx>, - possibly_unsatisfied_predicates: &mut Vec>) -> bool { - debug!("consider_probe: self_ty={:?} probe={:?}", - self_ty, - probe); + fn consider_probe(&self, + self_ty: Ty<'tcx>, + probe: &Candidate<'tcx>, + possibly_unsatisfied_predicates: &mut Vec>) + -> bool { + debug!("consider_probe: self_ty={:?} probe={:?}", self_ty, probe); self.probe(|_| { // First check that the self type can be related. - match self.sub_types(false, TypeOrigin::Misc(DUMMY_SP), - self_ty, probe.xform_self_ty) { + match self.sub_types(false, + TypeOrigin::Misc(DUMMY_SP), + self_ty, + probe.xform_self_ty) { Ok(InferOk { obligations, .. }) => { // FIXME(#32730) propagate obligations assert!(obligations.is_empty()) @@ -1093,14 +1086,11 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // Check whether the impl imposes obligations we have to worry about. let impl_bounds = self.tcx.lookup_predicates(impl_def_id); let impl_bounds = impl_bounds.instantiate(self.tcx, substs); - let traits::Normalized { value: impl_bounds, - obligations: norm_obligations } = + let traits::Normalized { value: impl_bounds, obligations: norm_obligations } = traits::normalize(selcx, cause.clone(), &impl_bounds); // Convert the bounds into obligations. - let obligations = - traits::predicates_for_generics(cause.clone(), - &impl_bounds); + let obligations = traits::predicates_for_generics(cause.clone(), &impl_bounds); debug!("impl_obligations={:?}", obligations); // Evaluate those obligations to see if they might possibly hold. @@ -1136,14 +1126,12 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { /// /// Now imagine the receiver is `Vec<_>`. It doesn't really matter at this time which impl we /// use, so it's ok to just commit to "using the method from the trait Foo". - fn collapse_candidates_to_trait_pick(&self, - probes: &[&Candidate<'tcx>]) - -> Option> { + fn collapse_candidates_to_trait_pick(&self, probes: &[&Candidate<'tcx>]) -> Option> { // Do all probes correspond to the same trait? let container = probes[0].item.container(); match container { ty::TraitContainer(_) => {} - ty::ImplContainer(_) => return None + ty::ImplContainer(_) => return None, } if probes[1..].iter().any(|p| p.item.container() != container) { return None; @@ -1156,7 +1144,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { import_id: probes[0].import_id, autoderefs: 0, autoref: None, - unsize: None + unsize: None, }) } @@ -1165,13 +1153,14 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn has_applicable_self(&self, item: &ty::ImplOrTraitItem) -> bool { // "fast track" -- check for usage of sugar match *item { - ty::ImplOrTraitItem::MethodTraitItem(ref method) => + ty::ImplOrTraitItem::MethodTraitItem(ref method) => { match method.explicit_self { ty::ExplicitSelfCategory::Static => self.mode == Mode::Path, ty::ExplicitSelfCategory::ByValue | ty::ExplicitSelfCategory::ByReference(..) | ty::ExplicitSelfCategory::ByBox => true, - }, + } + } ty::ImplOrTraitItem::ConstTraitItem(..) => self.mode == Mode::Path, _ => false, } @@ -1191,11 +1180,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { item: &ty::ImplOrTraitItem<'tcx>, impl_ty: Ty<'tcx>, substs: &Substs<'tcx>) - -> Ty<'tcx> - { + -> Ty<'tcx> { match item.as_opt_method() { - Some(ref method) => self.xform_method_self_ty(method, impl_ty, - substs), + Some(ref method) => self.xform_method_self_ty(method, impl_ty, substs), None => impl_ty, } } @@ -1204,8 +1191,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { method: &Rc>, impl_ty: Ty<'tcx>, substs: &Substs<'tcx>) - -> Ty<'tcx> - { + -> Ty<'tcx> { debug!("xform_self_ty(impl_ty={:?}, self_ty={:?}, substs={:?})", impl_ty, method.fty.sig.0.inputs.get(0), @@ -1218,8 +1204,10 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // are given do not include type/lifetime parameters for the // method yet. So create fresh variables here for those too, // if there are any. - assert_eq!(substs.types().count(), method.generics.parent_types as usize); - assert_eq!(substs.regions().count(), method.generics.parent_regions as usize); + assert_eq!(substs.types().count(), + method.generics.parent_types as usize); + assert_eq!(substs.regions().count(), + method.generics.parent_regions as usize); if self.mode == Mode::Path { return impl_ty; @@ -1233,7 +1221,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { if method.generics.types.is_empty() && method.generics.regions.is_empty() { xform_self_ty.subst(self.tcx, substs) } else { - let substs = Substs::for_item(self.tcx, method.def_id, |def, _| { + let substs = Substs::for_item(self.tcx, + method.def_id, + |def, _| { let i = def.index as usize; if i < substs.params().len() { substs.region_at(i) @@ -1242,7 +1232,8 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // `impl_self_ty()` for an explanation. self.tcx.mk_region(ty::ReErased) } - }, |def, cur_substs| { + }, + |def, cur_substs| { let i = def.index as usize; if i < substs.params().len() { substs.type_at(i) @@ -1255,13 +1246,11 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { } /// Get the type of an impl and generate substitutions with placeholders. - fn impl_ty_and_substs(&self, - impl_def_id: DefId) - -> (Ty<'tcx>, &'tcx Substs<'tcx>) - { + fn impl_ty_and_substs(&self, impl_def_id: DefId) -> (Ty<'tcx>, &'tcx Substs<'tcx>) { let impl_ty = self.tcx.lookup_item_type(impl_def_id).ty; - let substs = Substs::for_item(self.tcx, impl_def_id, + let substs = Substs::for_item(self.tcx, + impl_def_id, |_, _| self.tcx.mk_region(ty::ReErased), |_, _| self.next_ty_var()); @@ -1287,16 +1276,14 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { /// and/or tracking the substitution and /// so forth. fn erase_late_bound_regions(&self, value: &ty::Binder) -> T - where T : TypeFoldable<'tcx> + where T: TypeFoldable<'tcx> { self.tcx.erase_late_bound_regions(value) } /// Find item with name `item_name` defined in impl/trait `def_id` /// and return it, or `None`, if no such item was defined there. - fn impl_or_trait_item(&self, def_id: DefId) - -> Option> - { + fn impl_or_trait_item(&self, def_id: DefId) -> Option> { self.fcx.impl_or_trait_item(def_id, self.item_name) } } @@ -1307,9 +1294,7 @@ impl<'tcx> Candidate<'tcx> { item: self.item.clone(), kind: match self.kind { InherentImplCandidate(..) => InherentImplPick, - ExtensionImplCandidate(def_id, ..) => { - ExtensionImplPick(def_id) - } + ExtensionImplCandidate(def_id, ..) => ExtensionImplPick(def_id), ObjectCandidate => ObjectPick, TraitCandidate => TraitPick, WhereClauseCandidate(ref trait_ref) => { @@ -1326,15 +1311,13 @@ impl<'tcx> Candidate<'tcx> { import_id: self.import_id, autoderefs: 0, autoref: None, - unsize: None + unsize: None, } } fn to_source(&self) -> CandidateSource { match self.kind { - InherentImplCandidate(..) => { - ImplSource(self.item.container().id()) - } + InherentImplCandidate(..) => ImplSource(self.item.container().id()), ExtensionImplCandidate(def_id, ..) => ImplSource(def_id), ObjectCandidate | TraitCandidate | diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index ac8a35f08b0..e93f990b810 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -13,7 +13,7 @@ use CrateCtxt; -use check::{FnCtxt}; +use check::FnCtxt; use rustc::hir::map as hir_map; use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable}; use hir::def::Def; @@ -21,7 +21,7 @@ use hir::def_id::{CRATE_DEF_INDEX, DefId}; use middle::lang_items::FnOnceTraitLangItem; use rustc::ty::subst::Substs; use rustc::traits::{Obligation, SelectionContext}; -use util::nodemap::{FnvHashSet}; +use util::nodemap::FnvHashSet; use syntax::ast; use errors::DiagnosticBuilder; @@ -43,25 +43,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match ty.sty { // Not all of these (e.g. unsafe fns) implement FnOnce // so we look for these beforehand - ty::TyClosure(..) | ty::TyFnDef(..) | ty::TyFnPtr(_) => true, + ty::TyClosure(..) | + ty::TyFnDef(..) | + ty::TyFnPtr(_) => true, // If it's not a simple function, look for things which implement FnOnce _ => { let fn_once = match tcx.lang_items.require(FnOnceTraitLangItem) { Ok(fn_once) => fn_once, - Err(..) => return false + Err(..) => return false, }; - self.autoderef(span, ty).any(|(ty, _)| self.probe(|_| { - let fn_once_substs = - Substs::new_trait(tcx, ty, &[self.next_ty_var()]); - let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); - let poly_trait_ref = trait_ref.to_poly_trait_ref(); - let obligation = Obligation::misc(span, - self.body_id, - poly_trait_ref - .to_predicate()); - SelectionContext::new(self).evaluate_obligation(&obligation) - })) + self.autoderef(span, ty).any(|(ty, _)| { + self.probe(|_| { + let fn_once_substs = Substs::new_trait(tcx, ty, &[self.next_ty_var()]); + let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); + let poly_trait_ref = trait_ref.to_poly_trait_ref(); + let obligation = + Obligation::misc(span, self.body_id, poly_trait_ref.to_predicate()); + SelectionContext::new(self).evaluate_obligation(&obligation) + }) + }) } } } @@ -71,15 +72,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { rcvr_ty: Ty<'tcx>, item_name: ast::Name, rcvr_expr: Option<&hir::Expr>, - error: MethodError<'tcx>) - { + error: MethodError<'tcx>) { // avoid suggestions when we don't know what's going on. if rcvr_ty.references_error() { - return + return; } - let report_candidates = |err: &mut DiagnosticBuilder, - mut sources: Vec| { + let report_candidates = |err: &mut DiagnosticBuilder, mut sources: Vec| { sources.sort(); sources.dedup(); @@ -93,15 +92,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // the impl, if local to crate (item may be defaulted), else nothing. let item = self.impl_or_trait_item(impl_did, item_name) .or_else(|| { - self.impl_or_trait_item( - self.tcx.impl_trait_ref(impl_did).unwrap().def_id, + self.impl_or_trait_item(self.tcx + .impl_trait_ref(impl_did) + .unwrap() + .def_id, - item_name - ) - }).unwrap(); - let note_span = self.tcx.map.span_if_local(item.def_id()).or_else(|| { - self.tcx.map.span_if_local(impl_did) - }); + item_name) + }) + .unwrap(); + let note_span = self.tcx + .map + .span_if_local(item.def_id()) + .or_else(|| self.tcx.map.span_if_local(impl_did)); let impl_ty = self.impl_self_ty(span, impl_did).ty; @@ -128,7 +130,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { CandidateSource::TraitSource(trait_did) => { let item = self.impl_or_trait_item(trait_did, item_name).unwrap(); let item_span = self.tcx.map.def_id_span(item.def_id(), span); - span_note!(err, item_span, + span_note!(err, + item_span, "candidate #{} is defined in the trait `{}`", idx + 1, self.tcx.item_path_str(trait_did)); @@ -144,20 +147,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { MethodError::NoMatch(NoMatchData { static_candidates: static_sources, unsatisfied_predicates, out_of_scope_traits, - mode, .. }) => { + mode, + .. }) => { let tcx = self.tcx; - let mut err = self.type_error_struct( - span, - |actual| { - format!("no {} named `{}` found for type `{}` \ - in the current scope", - if mode == Mode::MethodCall { "method" } - else { "associated item" }, - item_name, - actual) - }, - rcvr_ty); + let mut err = self.type_error_struct(span, + |actual| { + format!("no {} named `{}` found for type `{}` in the current scope", + if mode == Mode::MethodCall { + "method" + } else { + "associated item" + }, + item_name, + actual) + }, + rcvr_ty); // If the method name is the name of a field with a function or closure type, // give a helping note that it has to be called as (x.f)(...). @@ -165,27 +170,30 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { for (ty, _) in self.autoderef(span, rcvr_ty) { match ty.sty { ty::TyAdt(def, substs) if !def.is_enum() => { - if let Some(field) = def.struct_variant(). - find_field_named(item_name) { + if let Some(field) = def.struct_variant() + .find_field_named(item_name) { let snippet = tcx.sess.codemap().span_to_snippet(expr.span); let expr_string = match snippet { Ok(expr_string) => expr_string, - _ => "s".into() // Default to a generic placeholder for the - // expression when we can't generate a - // string snippet + _ => "s".into(), // Default to a generic placeholder for the + // expression when we can't generate a + // string snippet }; let field_ty = field.ty(tcx, substs); if self.is_fn_ty(&field_ty, span) { - err.span_note(span, &format!( - "use `({0}.{1})(...)` if you meant to call the \ - function stored in the `{1}` field", - expr_string, item_name)); + err.span_note(span, + &format!("use `({0}.{1})(...)` if you \ + meant to call the function \ + stored in the `{1}` field", + expr_string, + item_name)); } else { - err.span_note(span, &format!( - "did you mean to write `{0}.{1}`?", - expr_string, item_name)); + err.span_note(span, + &format!("did you mean to write `{0}.{1}`?", + expr_string, + item_name)); } break; } @@ -204,10 +212,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } if let Some(expr) = rcvr_expr { - if let Ok (expr_string) = tcx.sess.codemap().span_to_snippet(expr.span) { + if let Ok(expr_string) = tcx.sess.codemap().span_to_snippet(expr.span) { report_function!(expr.span, expr_string); - } - else if let Expr_::ExprPath(_, path) = expr.node.clone() { + } else if let Expr_::ExprPath(_, path) = expr.node.clone() { if let Some(segment) = path.segments.last() { report_function!(expr.span, segment.name); } @@ -216,34 +223,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } if !static_sources.is_empty() { - err.note( - "found the following associated functions; to be used as \ - methods, functions must have a `self` parameter"); + err.note("found the following associated functions; to be used as methods, \ + functions must have a `self` parameter"); report_candidates(&mut err, static_sources); } if !unsatisfied_predicates.is_empty() { let bound_list = unsatisfied_predicates.iter() - .map(|p| format!("`{} : {}`", - p.self_ty(), - p)) + .map(|p| format!("`{} : {}`", p.self_ty(), p)) .collect::>() .join(", "); - err.note( - &format!("the method `{}` exists but the \ - following trait bounds were not satisfied: {}", - item_name, - bound_list)); + err.note(&format!("the method `{}` exists but the following trait bounds \ + were not satisfied: {}", + item_name, + bound_list)); } - self.suggest_traits_to_import(&mut err, span, rcvr_ty, item_name, - rcvr_expr, out_of_scope_traits); + self.suggest_traits_to_import(&mut err, + span, + rcvr_ty, + item_name, + rcvr_expr, + out_of_scope_traits); err.emit(); } MethodError::Ambiguity(sources) => { - let mut err = struct_span_err!(self.sess(), span, E0034, + let mut err = struct_span_err!(self.sess(), + span, + E0034, "multiple applicable items in scope"); err.span_label(span, &format!("multiple `{}` found", item_name)); @@ -255,11 +264,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let msg = format!("the `{}` method from the `{}` trait cannot be explicitly \ invoked on this closure as we have not yet inferred what \ kind of closure it is", - item_name, - self.tcx.item_path_str(trait_def_id)); + item_name, + self.tcx.item_path_str(trait_def_id)); let msg = if let Some(callee) = rcvr_expr { format!("{}; use overloaded call notation instead (e.g., `{}()`)", - msg, pprust::expr_to_string(callee)) + msg, + pprust::expr_to_string(callee)) } else { msg }; @@ -279,18 +289,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { rcvr_ty: Ty<'tcx>, item_name: ast::Name, rcvr_expr: Option<&hir::Expr>, - valid_out_of_scope_traits: Vec) - { + valid_out_of_scope_traits: Vec) { if !valid_out_of_scope_traits.is_empty() { let mut candidates = valid_out_of_scope_traits; candidates.sort(); candidates.dedup(); - let msg = format!( - "items from traits can only be used if the trait is in scope; \ - the following {traits_are} implemented but not in scope, \ - perhaps add a `use` for {one_of_them}:", - traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"}, - one_of_them = if candidates.len() == 1 {"it"} else {"one of them"}); + let msg = format!("items from traits can only be used if the trait is in scope; the \ + following {traits_are} implemented but not in scope, perhaps add \ + a `use` for {one_of_them}:", + traits_are = if candidates.len() == 1 { + "trait is" + } else { + "traits are" + }, + one_of_them = if candidates.len() == 1 { + "it" + } else { + "one of them" + }); err.help(&msg[..]); @@ -303,7 +319,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if candidates.len() > limit { err.note(&format!("and {} others", candidates.len() - limit)); } - return + return; } let type_is_local = self.type_derefs_to_local(span, rcvr_ty, rcvr_expr); @@ -319,8 +335,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // this isn't perfect (that is, there are cases when // implementing a trait would be legal but is rejected // here). - (type_is_local || info.def_id.is_local()) - && self.impl_or_trait_item(info.def_id, item_name).is_some() + (type_is_local || info.def_id.is_local()) && + self.impl_or_trait_item(info.def_id, item_name).is_some() }) .collect::>(); @@ -332,13 +348,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // FIXME #21673 this help message could be tuned to the case // of a type parameter: suggest adding a trait bound rather // than implementing. - let msg = format!( - "items from traits can only be used if the trait is implemented and in scope; \ - the following {traits_define} an item `{name}`, \ - perhaps you need to implement {one_of_them}:", - traits_define = if candidates.len() == 1 {"trait defines"} else {"traits define"}, - one_of_them = if candidates.len() == 1 {"it"} else {"one of them"}, - name = item_name); + let msg = format!("items from traits can only be used if the trait is implemented \ + and in scope; the following {traits_define} an item `{name}`, \ + perhaps you need to implement {one_of_them}:", + traits_define = if candidates.len() == 1 { + "trait defines" + } else { + "traits define" + }, + one_of_them = if candidates.len() == 1 { + "it" + } else { + "one of them" + }, + name = item_name); err.help(&msg[..]); @@ -355,7 +378,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn type_derefs_to_local(&self, span: Span, rcvr_ty: Ty<'tcx>, - rcvr_expr: Option<&hir::Expr>) -> bool { + rcvr_expr: Option<&hir::Expr>) + -> bool { fn is_local(ty: Ty) -> bool { match ty.sty { ty::TyAdt(def, _) => def.did.is_local(), @@ -368,7 +392,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // non-local (there are "edge" cases, e.g. (LocalType,), but // the noise from these sort of types is usually just really // annoying, rather than any sort of help). - _ => false + _ => false, } } @@ -391,9 +415,7 @@ pub struct TraitInfo { impl TraitInfo { fn new(def_id: DefId) -> TraitInfo { - TraitInfo { - def_id: def_id, - } + TraitInfo { def_id: def_id } } } impl PartialEq for TraitInfo { @@ -403,7 +425,9 @@ impl PartialEq for TraitInfo { } impl Eq for TraitInfo {} impl PartialOrd for TraitInfo { - fn partial_cmp(&self, other: &TraitInfo) -> Option { Some(self.cmp(other)) } + fn partial_cmp(&self, other: &TraitInfo) -> Option { + Some(self.cmp(other)) + } } impl Ord for TraitInfo { fn cmp(&self, other: &TraitInfo) -> Ordering { @@ -426,7 +450,7 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { // Crate-local: // // meh. - struct Visitor<'a, 'tcx:'a> { + struct Visitor<'a, 'tcx: 'a> { map: &'a hir_map::Map<'tcx>, traits: &'a mut AllTraitsVec, } @@ -443,7 +467,7 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { } ccx.tcx.map.krate().visit_all_items(&mut Visitor { map: &ccx.tcx.map, - traits: &mut traits + traits: &mut traits, }); // Cross-crate: @@ -469,7 +493,10 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { } } for cnum in ccx.tcx.sess.cstore.crates() { - let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX }; + let def_id = DefId { + krate: cnum, + index: CRATE_DEF_INDEX, + }; handle_external_def(ccx, &mut traits, &mut external_mods, Def::Mod(def_id)); } @@ -480,13 +507,13 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { assert!(borrow.is_some()); AllTraits { borrow: borrow, - idx: 0 + idx: 0, } } pub struct AllTraits<'a> { borrow: cell::Ref<'a, Option>, - idx: usize + idx: usize, } impl<'a> Iterator for AllTraits<'a> { diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs index 92c4899b3d5..66ff2fec832 100644 --- a/src/libstd/sys/unix/env.rs +++ b/src/libstd/sys/unix/env.rs @@ -140,7 +140,7 @@ pub mod os { } #[cfg(target_os = "haiku")] -mod os { +pub mod os { pub const FAMILY: &'static str = "unix"; pub const OS: &'static str = "haiku"; pub const DLL_PREFIX: &'static str = "lib"; @@ -151,7 +151,7 @@ mod os { } #[cfg(all(target_os = "emscripten", target_arch = "asmjs"))] -mod os { +pub mod os { pub const FAMILY: &'static str = "unix"; pub const OS: &'static str = "emscripten"; pub const DLL_PREFIX: &'static str = "lib"; @@ -162,7 +162,7 @@ mod os { } #[cfg(all(target_os = "emscripten", target_arch = "wasm32"))] -mod os { +pub mod os { pub const FAMILY: &'static str = "unix"; pub const OS: &'static str = "emscripten"; pub const DLL_PREFIX: &'static str = "lib"; diff --git a/src/rust-installer b/src/rust-installer index 755bc3db4ff..4f994850808 160000 --- a/src/rust-installer +++ b/src/rust-installer @@ -1 +1 @@ -Subproject commit 755bc3db4ff795865ea31b5b4f38ac920d8acacb +Subproject commit 4f994850808a572e2cc8d43f968893c8e942e9bf diff --git a/src/test/run-pass/issue-36856.rs b/src/test/run-pass/issue-36856.rs new file mode 100644 index 00000000000..91a0dadd653 --- /dev/null +++ b/src/test/run-pass/issue-36856.rs @@ -0,0 +1,24 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for #36856. + +// compile-flags:-g + +fn g() -> bool { + false +} + +pub fn main() { + let a = !g(); + if a != !g() { + panic!(); + } +} diff --git a/src/test/run-pass/issue-36936.rs b/src/test/run-pass/issue-36936.rs new file mode 100644 index 00000000000..34a9c291668 --- /dev/null +++ b/src/test/run-pass/issue-36936.rs @@ -0,0 +1,35 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// check that casts are not being treated as lexprs. + +fn main() { + let mut a = 0i32; + let b = &(a as i32); + a = 1; + assert_ne!(&a as *const i32, b as *const i32); + assert_eq!(*b, 0); + + assert_eq!(issue_36936(), 1); +} + + +struct A(u32); + +impl Drop for A { + fn drop(&mut self) { + self.0 = 0; + } +} + +fn issue_36936() -> u32 { + let a = &(A(1) as A); + a.0 +}