From 78aaa3e5468f7e23267659b99b20f9ef33cdad44 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 13 Oct 2018 11:32:49 +0200 Subject: [PATCH 1/2] Check the invariant for `principal` inside the method --- src/librustc/traits/coherence.rs | 10 +---- src/librustc/traits/select.rs | 27 ++++-------- src/librustc/ty/error.rs | 3 +- src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/item_path.rs | 2 +- src/librustc/ty/sty.rs | 16 +++---- src/librustc/ty/wf.rs | 2 +- src/librustc/util/ppaux.rs | 20 ++++----- src/librustc_codegen_llvm/context.rs | 2 +- .../debuginfo/metadata.rs | 7 +-- .../debuginfo/type_names.rs | 14 +++--- src/librustc_codegen_llvm/meth.rs | 24 +++++------ src/librustc_mir/interpret/cast.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 30 ++++++------- src/librustc_mir/monomorphize/item.rs | 13 +++--- src/librustc_privacy/lib.rs | 7 ++- src/librustc_typeck/check/cast.rs | 4 +- src/librustc_typeck/check/closure.rs | 4 +- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 7 ++- src/librustc_typeck/check/method/suggest.rs | 3 +- .../coherence/inherent_impls.rs | 4 +- src/librustc_typeck/coherence/mod.rs | 5 +-- .../outlives/implicit_infer.rs | 43 +++++++++---------- src/librustc_typeck/variance/constraints.rs | 10 ++--- 25 files changed, 112 insertions(+), 151 deletions(-) diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 7add8ef05ee78..817e9ffcbb55d 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -418,9 +418,7 @@ fn fundamental_ty(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool { match ty.sty { ty::Ref(..) => true, ty::Adt(def, _) => def.is_fundamental(), - ty::Dynamic(ref data, ..) => { - data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental")) - } + ty::Dynamic(ref data, ..) => tcx.has_attr(data.principal().def_id(), "fundamental"), _ => false } } @@ -467,11 +465,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool { ty::Adt(def, _) => def_id_is_local(def.did, in_crate), ty::Foreign(did) => def_id_is_local(did, in_crate), - ty::Dynamic(ref tt, ..) => { - tt.principal().map_or(false, |p| - def_id_is_local(p.def_id(), in_crate) - ) - } + ty::Dynamic(ref tt, ..) => def_id_is_local(tt.principal().def_id(), in_crate), ty::Error => true, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 82d881e10b168..8e8024e51da7f 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2088,10 +2088,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return; } - match data.principal() { - Some(p) => p.with_self_ty(this.tcx(), self_ty), - None => return, - } + data.principal().with_self_ty(this.tcx(), self_ty) } ty::Infer(ty::TyVar(_)) => { debug!("assemble_candidates_from_object_ty: ambiguous"); @@ -2183,15 +2180,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // // We always upcast when we can because of reason // #2 (region bounds). - match (data_a.principal(), data_b.principal()) { - (Some(a), Some(b)) => { - a.def_id() == b.def_id() - && data_b.auto_traits() - // All of a's auto traits need to be in b's auto traits. - .all(|b| data_a.auto_traits().any(|a| a == b)) - } - _ => false, - } + data_a.principal().def_id() == data_b.principal().def_id() + && data_b.auto_traits() + // All of a's auto traits need to be in b's auto traits. + .all(|b| data_a.auto_traits().any(|a| a == b)) } // T -> Trait. @@ -2981,7 +2973,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .shallow_resolve(*obligation.self_ty().skip_binder()); let poly_trait_ref = match self_ty.sty { ty::Dynamic(ref data, ..) => { - data.principal().unwrap().with_self_ty(self.tcx(), self_ty) + data.principal().with_self_ty(self.tcx(), self_ty) } _ => span_bug!(obligation.cause.span, "object candidate with non-object"), }; @@ -3244,10 +3236,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => { // See assemble_candidates_for_unsizing for more info. let existential_predicates = data_a.map_bound(|data_a| { - let principal = data_a.principal(); - let iter = principal - .into_iter() - .map(ty::ExistentialPredicate::Trait) + let iter = iter::once(ty::ExistentialPredicate::Trait(data_a.principal())) .chain( data_a .projection_bounds() @@ -3285,7 +3274,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // T -> Trait. (_, &ty::Dynamic(ref data, r)) => { let mut object_dids = data.auto_traits() - .chain(data.principal().map(|p| p.def_id())); + .chain(iter::once(data.principal().def_id())); if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) { return Err(TraitNotObjectSafe(did)); } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 3123f0fbe31de..d886d5ed20413 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -208,8 +208,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::FnDef(..) => "fn item".into(), ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(ref inner, ..) => { - inner.principal().map_or_else(|| "trait".into(), - |p| format!("trait {}", tcx.item_path_str(p.def_id())).into()) + format!("trait {}", tcx.item_path_str(inner.principal().def_id())).into() } ty::Closure(..) => "closure".into(), ty::Generator(..) => "generator".into(), diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 0f68e7aba4def..e6aaf8b1bb206 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -78,7 +78,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType), ty::RawPtr(_) => Some(PtrSimplifiedType), ty::Dynamic(ref trait_info, ..) => { - trait_info.principal().map(|p| TraitSimplifiedType(p.def_id())) + Some(TraitSimplifiedType(trait_info.principal().def_id())) } ty::Ref(_, ty, _) => { // since we introduce auto-refs during method lookup, we diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index ab0813240364c..c4a25971da3ad 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -436,7 +436,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { match ty.sty { ty::Adt(adt_def, _) => Some(adt_def.did), - ty::Dynamic(data, ..) => data.principal().map(|p| p.def_id()), + ty::Dynamic(data, ..) => Some(data.principal().def_id()), ty::Array(subty, _) | ty::Slice(subty) => characteristic_def_id_of_type(subty), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 145c122e75d68..cc6e6b2861ecb 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -559,10 +559,10 @@ impl<'a, 'gcx, 'tcx> Binder> { impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List> {} impl<'tcx> List> { - pub fn principal(&self) -> Option> { - match self.get(0) { - Some(&ExistentialPredicate::Trait(tr)) => Some(tr), - _ => None, + pub fn principal(&self) -> ExistentialTraitRef<'tcx> { + match self[0] { + ExistentialPredicate::Trait(tr) => tr, + other => bug!("first predicate is {:?}", other), } } @@ -589,8 +589,8 @@ impl<'tcx> List> { } impl<'tcx> Binder<&'tcx List>> { - pub fn principal(&self) -> Option> { - self.skip_binder().principal().map(Binder::bind) + pub fn principal(&self) -> PolyExistentialTraitRef<'tcx> { + Binder::bind(self.skip_binder().principal()) } #[inline] @@ -1825,9 +1825,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } Dynamic(ref obj, region) => { let mut v = vec![region]; - if let Some(p) = obj.principal() { - v.extend(p.skip_binder().substs.regions()); - } + v.extend(obj.principal().skip_binder().substs.regions()); v } Adt(_, substs) | Opaque(_, substs) => { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 7af838845cd61..27747970f76b2 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -387,7 +387,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { let cause = self.cause(traits::MiscObligation); let component_traits = - data.auto_traits().chain(data.principal().map(|p| p.def_id())); + data.auto_traits().chain(once(data.principal().def_id())); self.out.extend( component_traits.map(|did| traits::Obligation::new( cause.clone(), diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 33534ab27f147..f3b5503b8d0fc 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -621,16 +621,16 @@ define_print! { // Use a type that can't appear in defaults of type parameters. let dummy_self = tcx.mk_infer(ty::FreshTy(0)); - if let Some(p) = self.principal() { - let principal = tcx.lift(&p).expect("could not lift TraitRef for printing") - .with_self_ty(tcx, dummy_self); - let projections = self.projection_bounds().map(|p| { - tcx.lift(&p) - .expect("could not lift projection for printing") - .with_self_ty(tcx, dummy_self) - }).collect::>(); - cx.parameterized(f, principal.substs, principal.def_id, &projections)?; - } + let principal = tcx + .lift(&self.principal()) + .expect("could not lift TraitRef for printing") + .with_self_ty(tcx, dummy_self); + let projections = self.projection_bounds().map(|p| { + tcx.lift(&p) + .expect("could not lift projection for printing") + .with_self_ty(tcx, dummy_self) + }).collect::>(); + cx.parameterized(f, principal.substs, principal.def_id, &projections)?; // Builtin bounds. for did in self.auto_traits() { diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 578018c7adc8a..e619742373801 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -59,7 +59,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> { /// Cache instances of monomorphic and polymorphic items pub instances: RefCell, &'a Value>>, /// Cache generated vtables - pub vtables: RefCell, Option>), + pub vtables: RefCell, ty::PolyExistentialTraitRef<'tcx>), &'a Value>>, /// Cache of constant strings, pub const_cstr_cache: RefCell>, diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 706568b544661..6eff086a2ba05 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -435,12 +435,7 @@ fn trait_pointer_metadata( // But it does not describe the trait's methods. let containing_scope = match trait_type.sty { - ty::Dynamic(ref data, ..) => if let Some(principal) = data.principal() { - let def_id = principal.def_id(); - Some(get_namespace_for_item(cx, def_id)) - } else { - NO_SCOPE_METADATA - }, + ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())), _ => { bug!("debuginfo: Unexpected trait-object type in \ trait_pointer_metadata(): {:?}", diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs index 2f110fd552a8d..06b9318a5e830 100644 --- a/src/librustc_codegen_llvm/debuginfo/type_names.rs +++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs @@ -116,14 +116,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } }, ty::Dynamic(ref trait_data, ..) => { - if let Some(principal) = trait_data.principal() { - let principal = cx.tcx.normalize_erasing_late_bound_regions( - ty::ParamEnv::reveal_all(), - &principal, - ); - push_item_name(cx, principal.def_id, false, output); - push_type_params(cx, principal.substs, output); - } + let principal = cx.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &trait_data.principal(), + ); + push_item_name(cx, principal.def_id, false, output); + push_type_params(cx, principal.substs, output); }, ty::FnDef(..) | ty::FnPtr(_) => { let sig = t.fn_sig(cx.tcx); diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs index 8a1159bc4773c..db06b87f44e1e 100644 --- a/src/librustc_codegen_llvm/meth.rs +++ b/src/librustc_codegen_llvm/meth.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> VirtualIndex { pub fn get_vtable( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, - trait_ref: Option>, + trait_ref: ty::PolyExistentialTraitRef<'tcx>, ) -> &'ll Value { let tcx = cx.tcx; @@ -86,23 +86,19 @@ pub fn get_vtable( // Not in the cache. Build it. let nullptr = C_null(Type::i8p(cx)); + let methods = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty)); + let methods = methods.iter().cloned().map(|opt_mth| { + opt_mth.map_or(nullptr, |(def_id, substs)| { + callee::resolve_and_get_fn(cx, def_id, substs) + }) + }); + let (size, align) = cx.size_and_align_of(ty); - let mut components: Vec<_> = [ + let components: Vec<_> = [ callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)), C_usize(cx, size.bytes()), C_usize(cx, align.abi()) - ].iter().cloned().collect(); - - if let Some(trait_ref) = trait_ref { - let trait_ref = trait_ref.with_self_ty(tcx, ty); - let methods = tcx.vtable_methods(trait_ref); - let methods = methods.iter().cloned().map(|opt_mth| { - opt_mth.map_or(nullptr, |(def_id, substs)| { - callee::resolve_and_get_fn(cx, def_id, substs) - }) - }); - components.extend(methods); - } + ].iter().cloned().chain(methods).collect(); let vtable_const = C_struct(cx, &components, false); let align = cx.data_layout().pointer_align; diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index bfc7e6801fc46..32ce16212e4ee 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -326,7 +326,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } (_, &ty::Dynamic(ref data, _)) => { // Initial cast from sized to dyn trait - let trait_ref = data.principal().unwrap().with_self_ty( + let trait_ref = data.principal().with_self_ty( *self.tcx, src_pointee_ty, ); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 29f167629441b..dd83d3157ba61 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -907,22 +907,20 @@ fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, !impl_ty.needs_subst() && !impl_ty.has_escaping_regions()); if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty { - if let Some(principal) = trait_ty.principal() { - let poly_trait_ref = principal.with_self_ty(tcx, impl_ty); - assert!(!poly_trait_ref.has_escaping_regions()); - - // Walk all methods of the trait, including those of its supertraits - let methods = tcx.vtable_methods(poly_trait_ref); - let methods = methods.iter().cloned().filter_map(|method| method) - .map(|(def_id, substs)| ty::Instance::resolve( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - substs).unwrap()) - .filter(|&instance| should_monomorphize_locally(tcx, &instance)) - .map(|instance| create_fn_mono_item(instance)); - output.extend(methods); - } + let poly_trait_ref = trait_ty.principal().with_self_ty(tcx, impl_ty); + assert!(!poly_trait_ref.has_escaping_regions()); + + // Walk all methods of the trait, including those of its supertraits + let methods = tcx.vtable_methods(poly_trait_ref); + let methods = methods.iter().cloned().filter_map(|method| method) + .map(|(def_id, substs)| ty::Instance::resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + substs).unwrap()) + .filter(|&instance| should_monomorphize_locally(tcx, &instance)) + .map(|instance| create_fn_mono_item(instance)); + output.extend(methods); // Also add the destructor visit_drop_use(tcx, impl_ty, false, output); } diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index f0ea93bfffd3e..4c4d56c893838 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -320,12 +320,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.push(']'); }, ty::Dynamic(ref trait_data, ..) => { - if let Some(principal) = trait_data.principal() { - self.push_def_path(principal.def_id(), output); - self.push_type_params(principal.skip_binder().substs, - trait_data.projection_bounds(), - output); - } + let principal = trait_data.principal(); + self.push_def_path(principal.def_id(), output); + self.push_type_params( + principal.skip_binder().substs, + trait_data.projection_bounds(), + output, + ); }, ty::Foreign(did) => self.push_def_path(did, output), ty::FnDef(..) | diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 60679d6d4304e..989851bb1b9b4 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -93,8 +93,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { let ty_def_id = match self.tcx.type_of(item_def_id).sty { ty::Adt(adt, _) => adt.did, ty::Foreign(did) => did, - ty::Dynamic(ref obj, ..) if obj.principal().is_some() => - obj.principal().unwrap().def_id(), + ty::Dynamic(ref obj, ..) => obj.principal().def_id(), ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id, _ => return Some(AccessLevel::Public) }; @@ -484,7 +483,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b let ty_def_id = match ty.sty { ty::Adt(adt, _) => Some(adt.did), ty::Foreign(did) => Some(did), - ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()), + ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), ty::Projection(ref proj) => Some(proj.item_def_id), ty::FnDef(def_id, ..) | ty::Closure(def_id, ..) | @@ -1456,7 +1455,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<' let ty_def_id = match ty.sty { ty::Adt(adt, _) => Some(adt.did), ty::Foreign(did) => Some(did), - ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()), + ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()), ty::Projection(ref proj) => { if self.required_visibility == ty::Visibility::Invisible { // Conservatively approximate the whole type alias as public without diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 285fed9544ddb..e0ee26cba0828 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -73,7 +73,7 @@ enum PointerKind<'tcx> { /// No metadata attached, ie pointer to sized type or foreign type Thin, /// A trait object - Vtable(Option), + Vtable(DefId), /// Slice Length, /// The unsize info of this projection @@ -105,7 +105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Ok(match t.sty { ty::Slice(_) | ty::Str => Some(PointerKind::Length), ty::Dynamic(ref tty, ..) => - Some(PointerKind::Vtable(tty.principal().map(|p| p.def_id()))), + Some(PointerKind::Vtable(tty.principal().def_id())), ty::Adt(def, substs) if def.is_struct() => { match def.non_enum_variant().fields.last() { None => Some(PointerKind::Thin), diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 202789d1d8af6..940fa4d3916bc 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -198,9 +198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.deduce_sig_from_projection(None, &pb) }) .next(); - let kind = object_type - .principal() - .and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id())); + let kind = self.tcx.lang_items().fn_trait_kind(object_type.principal().def_id()); (sig, kind) } ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 4e5488b432d48..75f5bf74c6aef 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { .include_raw_pointers() .filter_map(|(ty, _)| match ty.sty { - ty::Dynamic(ref data, ..) => data.principal().map(|p| closure(self, ty, p)), + ty::Dynamic(ref data, ..) => Some(closure(self, ty, data.principal())), _ => None, } ) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index ec4483204f05e..ae02cd64c3891 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -452,10 +452,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { match self_ty.sty { ty::Dynamic(ref data, ..) => { - if let Some(p) = data.principal() { - self.assemble_inherent_candidates_from_object(self_ty, p); - self.assemble_inherent_impl_candidates_for_type(p.def_id()); - } + let p = data.principal(); + self.assemble_inherent_candidates_from_object(self_ty, p); + self.assemble_inherent_impl_candidates_for_type(p.def_id()); } ty::Adt(def, _) => { self.assemble_inherent_impl_candidates_for_type(def.did); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 28b9dcb9bfdd1..2006796a10089 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -663,8 +663,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Adt(def, _) => def.did.is_local(), ty::Foreign(did) => did.is_local(), - ty::Dynamic(ref tr, ..) => tr.principal() - .map_or(false, |p| p.def_id().is_local()), + ty::Dynamic(ref tr, ..) => tr.principal().def_id().is_local(), ty::Param(_) => true, diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 1955a709dbfe5..ec979dea4fd03 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -108,8 +108,8 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> { ty::Foreign(did) => { self.check_def_id(item, did); } - ty::Dynamic(ref data, ..) if data.principal().is_some() => { - self.check_def_id(item, data.principal().unwrap().def_id()); + ty::Dynamic(ref data, ..) => { + self.check_def_id(item, data.principal().def_id()); } ty::Char => { self.check_primitive_impl(def_id, diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 616ca97a7a75d..9b17654d4690c 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -181,13 +181,12 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI // This is something like impl Trait1 for Trait2. Illegal // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe. - if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) { + if !tcx.is_object_safe(data.principal().def_id()) { // This is an error, but it will be reported by wfcheck. Ignore it here. // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`. } else { let mut supertrait_def_ids = - traits::supertrait_def_ids(tcx, - data.principal().unwrap().def_id()); + traits::supertrait_def_ids(tcx, data.principal().def_id()); if supertrait_def_ids.any(|d| d == trait_def_id) { let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap()); struct_span_err!(tcx.sess, diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs index 254146c0ef3aa..132da8f5cea8d 100644 --- a/src/librustc_typeck/outlives/implicit_infer.rs +++ b/src/librustc_typeck/outlives/implicit_infer.rs @@ -203,28 +203,27 @@ fn insert_required_predicates_to_be_wf<'tcx>( debug!("Dynamic"); debug!("field_ty = {}", &field_ty); debug!("ty in field = {}", &ty); - if let Some(ex_trait_ref) = obj.principal() { - // Here, we are passing the type `usize` as a - // placeholder value with the function - // `with_self_ty`, since there is no concrete type - // `Self` for a `dyn Trait` at this - // stage. Therefore when checking explicit - // predicates in `check_explicit_predicates` we - // need to ignore checking the explicit_map for - // Self type. - let substs = ex_trait_ref - .with_self_ty(tcx, tcx.types.usize) - .skip_binder() - .substs; - check_explicit_predicates( - tcx, - &ex_trait_ref.skip_binder().def_id, - substs, - required_predicates, - explicit_map, - IgnoreSelfTy(true), - ); - } + let ex_trait_ref = obj.principal(); + // Here, we are passing the type `usize` as a + // placeholder value with the function + // `with_self_ty`, since there is no concrete type + // `Self` for a `dyn Trait` at this + // stage. Therefore when checking explicit + // predicates in `check_explicit_predicates` we + // need to ignore checking the explicit_map for + // Self type. + let substs = ex_trait_ref + .with_self_ty(tcx, tcx.types.usize) + .skip_binder() + .substs; + check_explicit_predicates( + tcx, + &ex_trait_ref.skip_binder().def_id, + substs, + required_predicates, + explicit_map, + IgnoreSelfTy(true), + ); } ty::Projection(obj) => { diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 32a591777db5b..3e523c0c7f559 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -311,11 +311,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { let contra = self.contravariant(variance); self.add_constraints_from_region(current, r, contra); - if let Some(p) = data.principal() { - let poly_trait_ref = p.with_self_ty(self.tcx(), self.tcx().types.err); - self.add_constraints_from_trait_ref( - current, *poly_trait_ref.skip_binder(), variance); - } + let poly_trait_ref = data + .principal() + .with_self_ty(self.tcx(), self.tcx().types.err); + self.add_constraints_from_trait_ref( + current, *poly_trait_ref.skip_binder(), variance); for projection in data.projection_bounds() { self.add_constraints_from_ty( From 585490d816b219dac781f763c2e3e4d2028b68ab Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 13 Oct 2018 19:41:27 +0200 Subject: [PATCH 2/2] Also adjust rustdoc to the principal changes --- src/librustdoc/clean/mod.rs | 73 ++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ddabef96c7c5e..2ba1f103971f0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2632,47 +2632,44 @@ impl<'tcx> Clean for Ty<'tcx> { } } ty::Dynamic(ref obj, ref reg) => { - if let Some(principal) = obj.principal() { - let did = principal.def_id(); + let principal = obj.principal(); + let did = principal.def_id(); + inline::record_extern_fqn(cx, did, TypeKind::Trait); + + let mut typarams = vec![]; + reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b))); + for did in obj.auto_traits() { + let empty = cx.tcx.intern_substs(&[]); + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), + Some(did), false, vec![], empty); inline::record_extern_fqn(cx, did, TypeKind::Trait); + let bound = GenericBound::TraitBound(PolyTrait { + trait_: ResolvedPath { + path, + typarams: None, + did, + is_generic: false, + }, + generic_params: Vec::new(), + }, hir::TraitBoundModifier::None); + typarams.push(bound); + } - let mut typarams = vec![]; - reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b))); - for did in obj.auto_traits() { - let empty = cx.tcx.intern_substs(&[]); - let path = external_path(cx, &cx.tcx.item_name(did).as_str(), - Some(did), false, vec![], empty); - inline::record_extern_fqn(cx, did, TypeKind::Trait); - let bound = GenericBound::TraitBound(PolyTrait { - trait_: ResolvedPath { - path, - typarams: None, - did, - is_generic: false, - }, - generic_params: Vec::new(), - }, hir::TraitBoundModifier::None); - typarams.push(bound); - } - - let mut bindings = vec![]; - for pb in obj.projection_bounds() { - bindings.push(TypeBinding { - name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), - ty: pb.skip_binder().ty.clean(cx) - }); - } + let mut bindings = vec![]; + for pb in obj.projection_bounds() { + bindings.push(TypeBinding { + name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), + ty: pb.skip_binder().ty.clean(cx) + }); + } - let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did), - false, bindings, principal.skip_binder().substs); - ResolvedPath { - path, - typarams: Some(typarams), - did, - is_generic: false, - } - } else { - Never + let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did), + false, bindings, principal.skip_binder().substs); + ResolvedPath { + path, + typarams: Some(typarams), + did, + is_generic: false, } } ty::Tuple(ref t) => Tuple(t.clean(cx)),