Skip to content

Commit 216cd1b

Browse files
committed
Remove !Unpin related bounds
1 parent 2ef8503 commit 216cd1b

File tree

9 files changed

+105
-881
lines changed

9 files changed

+105
-881
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_lint::builtin::SELF_CONSTRUCTOR_FROM_OUTER_ITEM;
2323
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
2424
use rustc_middle::ty::{
2525
self, AdtKind, CanonicalUserType, GenericArgsRef, GenericParamDefKind, IsIdentity,
26-
SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, Upcast, UserArgs,
26+
SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, UserArgs,
2727
UserSelfTy,
2828
};
2929
use rustc_middle::{bug, span_bug};
@@ -464,29 +464,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
464464
}
465465
}
466466

467-
pub(crate) fn register_negative_bound(
468-
&self,
469-
ty: Ty<'tcx>,
470-
def_id: DefId,
471-
cause: traits::ObligationCause<'tcx>,
472-
) {
473-
if !ty.references_error() {
474-
let trait_ref = ty::TraitRef::new(self.tcx, def_id, [ty]);
475-
let predicate =
476-
ty::TraitPredicate { trait_ref, polarity: ty::PredicatePolarity::Negative }
477-
.upcast(self.tcx);
478-
self.fulfillment_cx.borrow_mut().register_predicate_obligation(
479-
self,
480-
traits::Obligation {
481-
cause,
482-
recursion_depth: 0,
483-
param_env: self.param_env,
484-
predicate,
485-
},
486-
);
487-
}
488-
}
489-
490467
pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> LoweredTy<'tcx> {
491468
let ty = self.lowerer().lower_ty(hir_ty);
492469
self.register_wf_obligation(ty.into(), hir_ty.span, ObligationCauseCode::WellFormed(None));

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 14 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use rustc_span::edition::Edition;
2727
use rustc_span::source_map::Spanned;
2828
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym};
2929
use rustc_trait_selection::infer::InferCtxtExt;
30-
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
30+
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
3131
use tracing::{debug, instrument, trace};
3232
use ty::VariantDef;
3333
use ty::adjustment::{PatAdjust, PatAdjustment};
@@ -403,38 +403,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
403403
let ty = self.check_pat_inner(pat, opt_path_res, adjust_mode, expected, pat_info);
404404
self.write_ty(pat.hir_id, ty);
405405

406-
// If we implicitly inserted overloaded dereferences and pinned dereferences before matching,
407-
// check the pattern to see if the dereferenced types need `DerefMut` or `!Unpin` bounds.
408-
if let Some(derefed_tys) = self.typeck_results.borrow().pat_adjustments().get(pat.hir_id) {
409-
let mut has_overloaded_deref = false;
410-
let mut has_pin_deref = false;
411-
derefed_tys.iter().for_each(|adjust| match adjust.kind {
412-
PatAdjust::BuiltinDeref => {}
413-
PatAdjust::OverloadedDeref => has_overloaded_deref = true,
414-
PatAdjust::PinDeref => has_pin_deref = true,
415-
});
416-
if has_overloaded_deref {
417-
self.register_deref_mut_bounds_if_needed(
418-
pat.span,
419-
pat,
420-
derefed_tys.iter().filter_map(|adjust| match adjust.kind {
421-
PatAdjust::OverloadedDeref => Some(adjust.source),
422-
PatAdjust::BuiltinDeref | PatAdjust::PinDeref => None,
423-
}),
424-
);
425-
}
426-
if has_pin_deref {
427-
self.register_not_unpin_bounds_if_needed(
428-
pat.span,
429-
pat,
430-
derefed_tys.iter().filter_map(|adjust| match adjust.kind {
431-
PatAdjust::BuiltinDeref | PatAdjust::OverloadedDeref => None,
432-
PatAdjust::PinDeref => {
433-
Some(adjust.source.pinned_ref().expect("expected pinned reference").0)
434-
}
435-
}),
436-
);
437-
}
406+
// If we implicitly inserted overloaded dereferences before matching check the pattern to
407+
// see if the dereferenced types need `DerefMut` bounds.
408+
if let Some(derefed_tys) = self.typeck_results.borrow().pat_adjustments().get(pat.hir_id)
409+
&& derefed_tys.iter().any(|adjust| adjust.kind == PatAdjust::OverloadedDeref)
410+
{
411+
self.register_deref_mut_bounds_if_needed(
412+
pat.span,
413+
pat,
414+
derefed_tys.iter().filter_map(|adjust| match adjust.kind {
415+
PatAdjust::OverloadedDeref => Some(adjust.source),
416+
PatAdjust::BuiltinDeref | PatAdjust::PinDeref => None,
417+
}),
418+
);
438419
}
439420

440421
// (note_1): In most of the cases where (note_1) is referenced
@@ -583,9 +564,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
583564
self.misc(pat.span),
584565
)
585566
}
586-
// Once we've checked `pat`, we'll add a `!Unpin` bound if it contains any
587-
// `ref pin` bindings. See `Self::register_not_unpin_bounds_if_needed`.
588-
589567
debug!("default binding mode is now {:?}", binding_mode);
590568

591569
// Use the old pat info to keep `current_depth` to its old value.
@@ -2679,44 +2657,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26792657
}
26802658
}
26812659

2682-
/// Check if the interior of a pin pattern (either explicit or implicit) has any `ref pin`
2683-
/// bindings of non-`Unpin` types, which would require `!Unpin` to be emitted.
2684-
fn register_not_unpin_bounds_if_needed(
2685-
&self,
2686-
span: Span,
2687-
inner: &'tcx Pat<'tcx>,
2688-
derefed_tys: impl IntoIterator<Item = Ty<'tcx>>,
2689-
) {
2690-
// Check if there are subpatterns with `ref pin` binding modes of non-`Unpin` types.
2691-
let unpin = self.tcx.require_lang_item(hir::LangItem::Unpin, span);
2692-
let cause = self.misc(span);
2693-
let unpin_obligations = self.probe(|_| {
2694-
let ocx = ObligationCtxt::new(&self);
2695-
self.typeck_results.borrow().pat_walk_ref_pin_binding_of_non_unpin_type(inner, |ty| {
2696-
let ty = ocx
2697-
.normalize(&cause, self.param_env, ty)
2698-
.pinned_ref()
2699-
.expect("expect pinned reference")
2700-
.0;
2701-
debug!("check if `Unpin` is implemented for `{ty:?}`");
2702-
ocx.register_bound(cause.clone(), self.param_env, ty, unpin);
2703-
});
2704-
ocx.select_all_or_error()
2705-
});
2706-
2707-
// If any, the current pattern type should implement `!Unpin`.
2708-
if !unpin_obligations.is_empty() {
2709-
for pinned_derefed_ty in derefed_tys {
2710-
debug!("register `!Unpin` for `{pinned_derefed_ty:?}`");
2711-
self.register_negative_bound(
2712-
pinned_derefed_ty,
2713-
self.tcx.require_lang_item(hir::LangItem::Unpin, span),
2714-
self.misc(span),
2715-
);
2716-
}
2717-
}
2718-
}
2719-
27202660
// Precondition: Pat is Ref(inner)
27212661
fn check_pat_ref(
27222662
&self,

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 4 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -52,35 +52,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
5252

5353
let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
5454

55-
let def_id = obligation.predicate.def_id();
56-
let tcx = self.tcx();
57-
58-
let lang_item = tcx.as_lang_item(def_id);
59-
6055
// Negative trait predicates have different rules than positive trait predicates.
6156
if obligation.polarity() == ty::PredicatePolarity::Negative {
6257
self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
6358
self.assemble_candidates_from_impls(obligation, &mut candidates);
6459
self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
65-
66-
match lang_item {
67-
Some(LangItem::Unpin) if tcx.features().pin_ergonomics() => {
68-
debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());
69-
70-
// impl `!Unpin` automatically for tuples, slices, and arrays
71-
// to support projections for pinned patterns.
72-
self.assemble_builtin_neg_unpin_candidate(
73-
obligation.predicate.self_ty().skip_binder(),
74-
&mut candidates,
75-
);
76-
}
77-
_ => {}
78-
}
7960
} else {
8061
self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
8162

8263
// Other bounds. Consider both in-scope bounds from fn decl
8364
// and applicable impls. There is a certain set of precedence rules here.
65+
let def_id = obligation.predicate.def_id();
66+
let tcx = self.tcx();
67+
68+
let lang_item = tcx.as_lang_item(def_id);
8469
match lang_item {
8570
Some(LangItem::Copy | LangItem::Clone) => {
8671
debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());
@@ -1234,59 +1219,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12341219
}
12351220
}
12361221

1237-
/// Assembles `!Unpin` candidates for built-in types with no libcore-defined
1238-
/// `!Unpin` impls.
1239-
#[instrument(level = "debug", skip(self, candidates))]
1240-
fn assemble_builtin_neg_unpin_candidate(
1241-
&mut self,
1242-
self_ty: Ty<'tcx>,
1243-
candidates: &mut SelectionCandidateSet<'tcx>,
1244-
) {
1245-
match *self_ty.kind() {
1246-
// `Unpin` types
1247-
ty::FnDef(..)
1248-
| ty::FnPtr(..)
1249-
| ty::Error(_)
1250-
| ty::Uint(_)
1251-
| ty::Int(_)
1252-
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
1253-
| ty::Bool
1254-
| ty::Float(_)
1255-
| ty::Char
1256-
| ty::RawPtr(..)
1257-
| ty::Never
1258-
| ty::Ref(..)
1259-
| ty::Dynamic(..)
1260-
| ty::Str
1261-
| ty::Foreign(..)
1262-
| ty::UnsafeBinder(_)
1263-
| ty::Pat(..) => {}
1264-
1265-
ty::Array(..) | ty::Slice(_) | ty::Tuple(_) => {
1266-
candidates.vec.push(BuiltinCandidate);
1267-
}
1268-
1269-
// FIXME(pin_ergonomics): should we impl `!Unpin` for coroutines or closures?
1270-
ty::Coroutine(..)
1271-
| ty::CoroutineWitness(..)
1272-
| ty::Closure(..)
1273-
| ty::CoroutineClosure(..) => {}
1274-
1275-
ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {}
1276-
1277-
ty::Infer(ty::TyVar(_)) => {
1278-
candidates.ambiguous = true;
1279-
}
1280-
1281-
// We can make this an ICE if/once we actually instantiate the trait obligation eagerly.
1282-
ty::Bound(..) => {}
1283-
1284-
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1285-
bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty);
1286-
}
1287-
}
1288-
}
1289-
12901222
/// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself.
12911223
#[instrument(level = "debug", skip(self, candidates))]
12921224
fn assemble_builtin_sized_candidate(

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
269269
bug!("`PointeeSized` is removing during lowering");
270270
}
271271
Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(self_ty),
272-
Some(LangItem::Unpin) if obligation.polarity() == ty::PredicatePolarity::Negative => {
273-
self.neg_unpin_conditions(self_ty)
274-
}
275272
Some(LangItem::FusedIterator) => {
276273
if self.coroutine_is_gen(self_ty) {
277274
ty::Binder::dummy(vec![])
@@ -297,7 +294,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
297294
cause,
298295
obligation.recursion_depth + 1,
299296
trait_def,
300-
obligation.polarity(),
301297
types,
302298
)
303299
}
@@ -424,7 +420,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
424420
cause.clone(),
425421
obligation.recursion_depth + 1,
426422
obligation.predicate.def_id(),
427-
obligation.polarity(),
428423
constituents.types,
429424
);
430425

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,52 +2232,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
22322232
}
22332233
}
22342234

2235-
fn neg_unpin_conditions(&mut self, self_ty: Ty<'tcx>) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
2236-
match *self_ty.kind() {
2237-
ty::Array(ty, _) | ty::Slice(ty) => {
2238-
// (*) binder moved here
2239-
ty::Binder::dummy(vec![ty])
2240-
}
2241-
ty::Tuple(tys) => {
2242-
// (*) binder moved here
2243-
ty::Binder::dummy(tys.iter().collect())
2244-
}
2245-
2246-
// `Unpin` types
2247-
ty::FnDef(..)
2248-
| ty::FnPtr(..)
2249-
| ty::Error(_)
2250-
| ty::Uint(_)
2251-
| ty::Int(_)
2252-
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
2253-
| ty::Bool
2254-
| ty::Float(_)
2255-
| ty::Char
2256-
| ty::RawPtr(..)
2257-
| ty::Never
2258-
| ty::Ref(..)
2259-
| ty::Dynamic(..)
2260-
| ty::Str
2261-
| ty::Foreign(..)
2262-
| ty::UnsafeBinder(_)
2263-
| ty::Pat(..) => bug!("`Unpin` type cannot have `!Unpin` bound"),
2264-
2265-
ty::Coroutine(..)
2266-
| ty::CoroutineWitness(..)
2267-
| ty::Closure(..)
2268-
| ty::CoroutineClosure(..)
2269-
| ty::Infer(ty::TyVar(_))
2270-
| ty::Bound(..)
2271-
| ty::Adt(..)
2272-
| ty::Alias(..)
2273-
| ty::Param(..)
2274-
| ty::Placeholder(..)
2275-
| ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
2276-
bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty)
2277-
}
2278-
}
2279-
}
2280-
22812235
fn coroutine_is_gen(&mut self, self_ty: Ty<'tcx>) -> bool {
22822236
matches!(*self_ty.kind(), ty::Coroutine(did, ..)
22832237
if self.tcx().coroutine_is_gen(did))
@@ -2428,7 +2382,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
24282382
cause: ObligationCause<'tcx>,
24292383
recursion_depth: usize,
24302384
trait_def_id: DefId,
2431-
polarity: ty::PredicatePolarity,
24322385
types: Vec<Ty<'tcx>>,
24332386
) -> PredicateObligations<'tcx> {
24342387
// Because the types were potentially derived from
@@ -2473,10 +2426,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
24732426
ty::TraitRef::new_from_args(tcx, trait_def_id, err_args)
24742427
};
24752428

2476-
let trait_predicate = ty::TraitPredicate { trait_ref, polarity };
2477-
24782429
let obligation =
2479-
Obligation::new(self.tcx(), cause.clone(), param_env, trait_predicate);
2430+
Obligation::new(self.tcx(), cause.clone(), param_env, trait_ref);
24802431
obligations.push(obligation);
24812432
obligations
24822433
})

0 commit comments

Comments
 (0)