From aac0affa0a9a40a909383242a5075a592c3bcb98 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 21 Dec 2024 17:05:40 +0000 Subject: [PATCH] Begin to implement type system layer of unsafe binders --- compiler/rustc_ast_passes/src/feature_gate.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 2 + .../src/debuginfo/type_names.rs | 1 + .../src/const_eval/valtrees.rs | 8 +- .../src/interpret/intrinsics.rs | 1 + .../rustc_const_eval/src/interpret/stack.rs | 2 + .../src/interpret/validity.rs | 1 + .../rustc_const_eval/src/util/type_name.rs | 3 +- .../src/coherence/inherent_impls.rs | 3 +- .../src/coherence/orphan.rs | 3 +- .../src/hir_ty_lowering/mod.rs | 14 +-- .../src/variance/constraints.rs | 5 + compiler/rustc_hir_typeck/src/cast.rs | 2 + compiler/rustc_hir_typeck/src/expr.rs | 98 +++++++++++++++++-- .../src/infer/canonical/canonicalizer.rs | 1 + compiler/rustc_lint/src/types.rs | 2 + compiler/rustc_middle/src/ty/context.rs | 4 +- compiler/rustc_middle/src/ty/error.rs | 1 + compiler/rustc_middle/src/ty/flags.rs | 6 ++ compiler/rustc_middle/src/ty/layout.rs | 5 + compiler/rustc_middle/src/ty/print/mod.rs | 1 + compiler/rustc_middle/src/ty/print/pretty.rs | 4 + .../rustc_middle/src/ty/structural_impls.rs | 2 + compiler/rustc_middle/src/ty/sty.rs | 18 +++- compiler/rustc_middle/src/ty/util.rs | 10 +- compiler/rustc_middle/src/ty/walk.rs | 3 + .../src/move_paths/builder.rs | 2 + .../src/dataflow_const_prop.rs | 3 +- .../src/lint_tail_expr_drop_order.rs | 4 +- .../src/canonicalizer.rs | 1 + .../rustc_next_trait_solver/src/coherence.rs | 4 +- .../src/solve/assembly/mod.rs | 2 + .../src/solve/assembly/structural_traits.rs | 15 ++- .../src/solve/normalizes_to/mod.rs | 15 +++ .../src/solve/trait_goals.rs | 3 +- compiler/rustc_pattern_analysis/src/rustc.rs | 1 + compiler/rustc_privacy/src/lib.rs | 1 + .../src/cfi/typeid/itanium_cxx_abi/encode.rs | 5 + .../cfi/typeid/itanium_cxx_abi/transform.rs | 3 +- .../rustc_smir/src/rustc_smir/convert/ty.rs | 2 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_symbol_mangling/src/v0.rs | 3 + .../traits/fulfillment_errors.rs | 1 + .../src/traits/project.rs | 5 + .../src/traits/query/dropck_outlives.rs | 8 +- .../src/traits/select/candidate_assembly.rs | 9 +- .../src/traits/select/mod.rs | 10 ++ .../rustc_trait_selection/src/traits/wf.rs | 3 + compiler/rustc_ty_utils/src/instance.rs | 3 +- compiler/rustc_ty_utils/src/layout.rs | 5 + compiler/rustc_ty_utils/src/needs_drop.rs | 5 + compiler/rustc_ty_utils/src/ty.rs | 2 + compiler/rustc_type_ir/src/binder.rs | 8 +- compiler/rustc_type_ir/src/fast_reject.rs | 12 ++- compiler/rustc_type_ir/src/inherent.rs | 3 + compiler/rustc_type_ir/src/outlives.rs | 1 + compiler/rustc_type_ir/src/relate.rs | 4 + compiler/rustc_type_ir/src/ty_kind.rs | 73 +++++++++++++- src/librustdoc/clean/mod.rs | 2 + .../passes/collect_intra_doc_links.rs | 1 + .../clippy/clippy_lints/src/dereference.rs | 3 +- src/tools/clippy/clippy_utils/src/visitors.rs | 4 +- tests/debuginfo/function-names.rs | 2 +- .../feature-gates/feature-gate-auto-traits.rs | 2 +- .../feature-gate-auto-traits.stderr | 2 +- tests/ui/symbol-names/basic.legacy.stderr | 4 +- .../ui/symbol-names/issue-60925.legacy.stderr | 4 +- .../feature-gate-negative_impls.rs | 2 +- .../feature-gate-negative_impls.stderr | 2 +- tests/ui/unsafe-binders/expr.rs | 11 ++- tests/ui/unsafe-binders/expr.stderr | 24 ++--- .../ui/unsafe-binders/lifetime-resolution.rs | 7 +- .../unsafe-binders/lifetime-resolution.stderr | 24 +---- tests/ui/unsafe-binders/mismatch.rs | 43 ++++++++ tests/ui/unsafe-binders/mismatch.stderr | 68 +++++++++++++ tests/ui/unsafe-binders/simple.rs | 3 +- tests/ui/unsafe-binders/simple.stderr | 10 +- 77 files changed, 528 insertions(+), 109 deletions(-) create mode 100644 tests/ui/unsafe-binders/mismatch.rs create mode 100644 tests/ui/unsafe-binders/mismatch.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index f885b20c7611f..3fbf121018615 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -263,7 +263,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { &self, negative_impls, span.to(of_trait.as_ref().map_or(span, |t| t.path.span)), - "negative trait bounds are not yet fully implemented; \ + "negative trait bounds are not fully implemented; \ use marker types for now" ); } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8ee1b1d0ae693..ac0293848cca6 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1613,6 +1613,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) + | ty::UnsafeBinder(_) | ty::Alias(_, _) | ty::Param(_) | ty::Bound(_, _) @@ -1654,6 +1655,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { | ty::Dynamic(_, _, _) | ty::CoroutineWitness(..) | ty::Never + | ty::UnsafeBinder(_) | ty::Alias(_, _) | ty::Param(_) | ty::Bound(_, _) diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index cf72c2ed7423b..869798d8be194 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -432,6 +432,7 @@ fn push_debuginfo_type_name<'tcx>( push_closure_or_coroutine_name(tcx, def_id, args, qualified, output, visited); } } + ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binders)"), ty::Param(_) | ty::Error(_) | ty::Infer(_) diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 6f51b09323d9b..4ff8aa9a3b418 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -178,7 +178,8 @@ fn const_to_valtree_inner<'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) => Err(ValTreeCreationError::NonSupportedType(ty)), + | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) => Err(ValTreeCreationError::NonSupportedType(ty)), } } @@ -358,7 +359,10 @@ pub fn valtree_to_const_value<'tcx>( | ty::FnPtr(..) | ty::Str | ty::Slice(_) - | ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()), + | ty::Dynamic(..) + | ty::UnsafeBinder(_) => { + bug!("no ValTree should have been created for type {:?}", ty.kind()) + } } } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 1af8438534fd5..e9eca8814c3c1 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -90,6 +90,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(_) | ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx), diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 6512675530a45..7d0e0492792a9 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -505,6 +505,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // We don't want to do any queries, so there is not much we can do with ADTs. ty::Adt(..) => false, + ty::UnsafeBinder(ty) => is_very_trivially_sized(ty.skip_binder()), + ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false, ty::Infer(ty::TyVar(_)) => false, diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 6f101395ccf43..d75df1ad4425b 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -768,6 +768,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { // Nothing to check. interp_ok(true) } + ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), // The above should be all the primitive types. The rest is compound, we // check them by visiting their fields/variants. ty::Adt(..) diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index 36c7bed5c1194..e14cd603c5828 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -38,7 +38,8 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { | ty::FnPtr(..) | ty::Never | ty::Tuple(_) - | ty::Dynamic(_, _, _) => self.pretty_print_type(ty), + | ty::Dynamic(_, _, _) + | ty::UnsafeBinder(_) => self.pretty_print_type(ty), // Placeholders (all printed as `_` to uniformize them). ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 8f6f5b5f22215..a86dede48bffd 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -178,7 +178,8 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Ref(..) | ty::Never | ty::FnPtr(..) - | ty::Tuple(..) => self.check_primitive_impl(id, self_ty), + | ty::Tuple(..) + | ty::UnsafeBinder(_) => self.check_primitive_impl(id, self_ty), ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) | ty::Param(_) => { Err(self.tcx.dcx().emit_err(errors::InherentNominal { span: item_span })) } diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index eca85c22a40eb..7d651155781a1 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -225,7 +225,8 @@ pub(crate) fn orphan_check_impl( | ty::FnDef(..) | ty::FnPtr(..) | ty::Never - | ty::Tuple(..) => (LocalImpl::Allow, NonlocalImpl::DisallowOther), + | ty::Tuple(..) + | ty::UnsafeBinder(_) => (LocalImpl::Allow, NonlocalImpl::DisallowOther), ty::Closure(..) | ty::CoroutineClosure(..) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index b56222763d032..2154568c51267 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2318,13 +2318,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)), ) } - hir::TyKind::UnsafeBinder(_binder) => { - let guar = self - .dcx() - .struct_span_err(hir_ty.span, "unsafe binders are not yet implemented") - .emit(); - Ty::new_error(tcx, guar) - } + hir::TyKind::UnsafeBinder(binder) => Ty::new_unsafe_binder( + tcx, + ty::Binder::bind_with_vars( + self.lower_ty(binder.inner_ty), + tcx.late_bound_vars(hir_ty.hir_id), + ), + ), hir::TyKind::TraitObject(bounds, lifetime, repr) => { if let Some(guar) = self.prohibit_or_lint_bare_trait_object_ty(hir_ty) { // Don't continue with type analysis if the `dyn` keyword is missing diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 415b23d812b5f..e954d2b9ea48e 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -322,6 +322,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_sig(current, sig_tys.with(hdr), variance); } + ty::UnsafeBinder(ty) => { + // FIXME(unsafe_binders): This is covariant, right? + self.add_constraints_from_ty(current, ty.skip_binder(), variance); + } + ty::Error(_) => { // we encounter this when walking the trait references for object // types, where we use Error as the Self type diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 8190095971b64..7b07e0ee939c5 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -116,6 +116,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(&f) => self.pointer_kind(f, span)?, }, + ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), + // Pointers to foreign types are thin, despite being unsized ty::Foreign(..) => Some(PointerKind::Thin), // We should really try to normalize here. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index caea53d9200f4..5e7dc4370d9b3 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -574,8 +574,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_expr_index(base, idx, expr, brackets_span) } ExprKind::Yield(value, _) => self.check_expr_yield(value, expr), - ExprKind::UnsafeBinderCast(kind, expr, ty) => { - self.check_expr_unsafe_binder_cast(kind, expr, ty, expected) + ExprKind::UnsafeBinderCast(kind, inner_expr, ty) => { + self.check_expr_unsafe_binder_cast(expr.span, kind, inner_expr, ty, expected) } ExprKind::Err(guar) => Ty::new_error(tcx, guar), } @@ -1649,14 +1649,94 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_expr_unsafe_binder_cast( &self, - _kind: hir::UnsafeBinderCastKind, - expr: &'tcx hir::Expr<'tcx>, - _hir_ty: Option<&'tcx hir::Ty<'tcx>>, - _expected: Expectation<'tcx>, + span: Span, + kind: hir::UnsafeBinderCastKind, + inner_expr: &'tcx hir::Expr<'tcx>, + hir_ty: Option<&'tcx hir::Ty<'tcx>>, + expected: Expectation<'tcx>, ) -> Ty<'tcx> { - let guar = - self.dcx().struct_span_err(expr.span, "unsafe binders are not yet implemented").emit(); - Ty::new_error(self.tcx, guar) + self.dcx().span_err(inner_expr.span, "unsafe binder casts are not fully implemented"); + + match kind { + hir::UnsafeBinderCastKind::Wrap => { + let ascribed_ty = + hir_ty.map(|hir_ty| self.lower_ty_saving_user_provided_ty(hir_ty)); + let expected_ty = expected.only_has_type(self); + let binder_ty = match (ascribed_ty, expected_ty) { + (Some(ascribed_ty), Some(expected_ty)) => { + self.demand_eqtype(inner_expr.span, expected_ty, ascribed_ty); + expected_ty + } + (Some(ty), None) | (None, Some(ty)) => ty, + // This will always cause a structural resolve error, but we do it + // so we don't need to manually report an E0282 both on this codepath + // and in the others; it all happens in `structurally_resolve_type`. + (None, None) => self.next_ty_var(inner_expr.span), + }; + + let binder_ty = self.structurally_resolve_type(inner_expr.span, binder_ty); + let hint_ty = match *binder_ty.kind() { + ty::UnsafeBinder(binder) => self.instantiate_binder_with_fresh_vars( + inner_expr.span, + infer::BoundRegionConversionTime::HigherRankedType, + binder.into(), + ), + ty::Error(e) => Ty::new_error(self.tcx, e), + _ => { + let guar = self + .dcx() + .struct_span_err( + hir_ty.map_or(span, |hir_ty| hir_ty.span), + format!( + "`wrap_binder!()` can only wrap into unsafe binder, not {}", + binder_ty.sort_string(self.tcx) + ), + ) + .with_note("unsafe binders are the only valid output of wrap") + .emit(); + Ty::new_error(self.tcx, guar) + } + }; + + self.check_expr_has_type_or_error(inner_expr, hint_ty, |_| {}); + + binder_ty + } + hir::UnsafeBinderCastKind::Unwrap => { + let ascribed_ty = + hir_ty.map(|hir_ty| self.lower_ty_saving_user_provided_ty(hir_ty)); + let hint_ty = ascribed_ty.unwrap_or_else(|| self.next_ty_var(inner_expr.span)); + // FIXME(unsafe_binders): coerce here if needed? + let binder_ty = self.check_expr_has_type_or_error(inner_expr, hint_ty, |_| {}); + + // Unwrap the binder. This will be ambiguous if it's an infer var, and will error + // if it's not an unsafe binder. + let binder_ty = self.structurally_resolve_type(inner_expr.span, binder_ty); + match *binder_ty.kind() { + ty::UnsafeBinder(binder) => self.instantiate_binder_with_fresh_vars( + inner_expr.span, + infer::BoundRegionConversionTime::HigherRankedType, + binder.into(), + ), + ty::Error(e) => Ty::new_error(self.tcx, e), + _ => { + let guar = self + .dcx() + .struct_span_err( + hir_ty.map_or(inner_expr.span, |hir_ty| hir_ty.span), + format!( + "expected unsafe binder, found {} as input of \ + `unwrap_binder!()`", + binder_ty.sort_string(self.tcx) + ), + ) + .with_note("only an unsafe binder type can be unwrapped") + .emit(); + Ty::new_error(self.tcx, guar) + } + } + } + } } fn check_expr_array( diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index fe66d306ceb80..c47f27e871f7a 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -441,6 +441,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { | ty::FnDef(..) | ty::FnPtr(..) | ty::Dynamic(..) + | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(..) | ty::Alias(..) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index c0371b1f606d3..ef9aa11ef7b8b 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1284,6 +1284,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { FfiSafe } + ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), + ty::Param(..) | ty::Alias(ty::Projection | ty::Inherent | ty::Weak, ..) | ty::Infer(..) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 977e62becf169..d26c007d227df 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -471,7 +471,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(_, _) | ty::Never - | ty::Tuple(_) => { + | ty::Tuple(_) + | ty::UnsafeBinder(_) => { let simp = ty::fast_reject::simplify_type( tcx, self_ty, @@ -2295,6 +2296,7 @@ impl<'tcx> TyCtxt<'tcx> { Ref, FnDef, FnPtr, + UnsafeBinder, Placeholder, Coroutine, CoroutineWitness, diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 4a82af3255950..714094db0530f 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -191,6 +191,7 @@ impl<'tcx> Ty<'tcx> { _ => "fn item".into(), }, ty::FnPtr(..) => "fn pointer".into(), + ty::UnsafeBinder(_) => "unsafe binder".into(), ty::Dynamic(..) => "trait object".into(), ty::Closure(..) | ty::CoroutineClosure(..) => "closure".into(), ty::Coroutine(def_id, ..) => { diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 04d03187541ce..0af57f636aaab 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -253,6 +253,12 @@ impl FlagComputation { &ty::FnPtr(sig_tys, _) => self.bound_computation(sig_tys, |computation, sig_tys| { computation.add_tys(sig_tys.inputs_and_output); }), + + &ty::UnsafeBinder(bound_ty) => { + self.bound_computation(bound_ty.into(), |computation, ty| { + computation.add_ty(ty); + }) + } } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 367b0c07f9bc4..6e6da6de749a1 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -816,6 +816,11 @@ where bug!("TyAndLayout::field({:?}): not applicable", this) } + ty::UnsafeBinder(bound_ty) => { + let ty = tcx.instantiate_bound_regions_with_erased(bound_ty.into()); + field_ty_or_layout(TyAndLayout { ty, ..this }, cx, i) + } + // Potentially-wide pointers. ty::Ref(_, pointee, _) | ty::RawPtr(pointee, _) => { assert!(i < this.fields.count()); diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index cc7467467603a..b0150bc11920b 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -291,6 +291,7 @@ fn characteristic_def_id_of_type_cached<'a>( | ty::Uint(_) | ty::Str | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Alias(..) | ty::Placeholder(..) | ty::Param(_) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index a089eac5d7e1d..8e89331ef03c3 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -695,6 +695,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } } ty::FnPtr(ref sig_tys, hdr) => p!(print(sig_tys.with(hdr))), + ty::UnsafeBinder(ref bound_ty) => { + // FIXME(unsafe_binders): Make this print `unsafe<>` rather than `for<>`. + self.wrap_binder(bound_ty, |ty, cx| cx.pretty_print_type(*ty))?; + } ty::Infer(infer_ty) => { if self.should_print_verbose() { p!(write("{:?}", ty.kind())); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index f38454ceac019..68cb56f35837d 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -393,6 +393,7 @@ impl<'tcx> TypeSuperFoldable> for Ty<'tcx> { ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?), ty::FnDef(def_id, args) => ty::FnDef(def_id, args.try_fold_with(folder)?), ty::FnPtr(sig_tys, hdr) => ty::FnPtr(sig_tys.try_fold_with(folder)?, hdr), + ty::UnsafeBinder(f) => ty::UnsafeBinder(f.try_fold_with(folder)?), ty::Ref(r, ty, mutbl) => { ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl) } @@ -443,6 +444,7 @@ impl<'tcx> TypeSuperVisitable> for Ty<'tcx> { ty::Tuple(ts) => ts.visit_with(visitor), ty::FnDef(_, args) => args.visit_with(visitor), ty::FnPtr(ref sig_tys, _) => sig_tys.visit_with(visitor), + ty::UnsafeBinder(ref f) => f.visit_with(visitor), ty::Ref(r, ty, _) => { try_visit!(r.visit_with(visitor)); ty.visit_with(visitor) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 045c483d6a58a..92b3632c8acc7 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -673,6 +673,11 @@ impl<'tcx> Ty<'tcx> { Ty::new(tcx, FnPtr(sig_tys, hdr)) } + #[inline] + pub fn new_unsafe_binder(tcx: TyCtxt<'tcx>, b: Binder<'tcx, Ty<'tcx>>) -> Ty<'tcx> { + Ty::new(tcx, UnsafeBinder(b.into())) + } + #[inline] pub fn new_dynamic( tcx: TyCtxt<'tcx>, @@ -962,6 +967,10 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> { Ty::new_pat(interner, ty, pat) } + fn new_unsafe_binder(interner: TyCtxt<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>) -> Self { + Ty::new_unsafe_binder(interner, ty) + } + fn new_unit(interner: TyCtxt<'tcx>) -> Self { interner.types.unit } @@ -1480,6 +1489,7 @@ impl<'tcx> Ty<'tcx> { | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) + | ty::UnsafeBinder(_) | ty::Error(_) | ty::Infer(IntVar(_) | FloatVar(_)) => tcx.types.u8, @@ -1659,6 +1669,8 @@ impl<'tcx> Ty<'tcx> { // metadata of `tail`. ty::Param(_) | ty::Alias(..) => Err(tail), + | ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), + ty::Infer(ty::TyVar(_)) | ty::Pat(..) | ty::Bound(..) @@ -1819,6 +1831,7 @@ impl<'tcx> Ty<'tcx> { | ty::Float(_) | ty::FnDef(..) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::RawPtr(..) | ty::Char | ty::Ref(..) @@ -1898,6 +1911,8 @@ impl<'tcx> Ty<'tcx> { // Might be, but not "trivial" so just giving the safe answer. ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) => false, + ty::UnsafeBinder(_) => false, + // Needs normalization or revealing to determine, so no is the safe answer. ty::Alias(..) => false, @@ -1976,7 +1991,8 @@ impl<'tcx> Ty<'tcx> { | Coroutine(_, _) | CoroutineWitness(..) | Never - | Tuple(_) => true, + | Tuple(_) + | UnsafeBinder(_) => true, Error(_) | Infer(_) | Alias(_, _) | Param(_) | Bound(_, _) | Placeholder(_) => false, } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index fc3530e3dde97..ab8285f87d6ce 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1241,6 +1241,7 @@ impl<'tcx> Ty<'tcx> { | ty::Foreign(_) | ty::Coroutine(..) | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) | ty::Infer(_) | ty::Alias(..) | ty::Param(_) @@ -1281,6 +1282,7 @@ impl<'tcx> Ty<'tcx> { | ty::Foreign(_) | ty::Coroutine(..) | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) | ty::Infer(_) | ty::Alias(..) | ty::Param(_) @@ -1322,6 +1324,9 @@ impl<'tcx> Ty<'tcx> { | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => AsyncDropGlueMorphology::Noop, + // FIXME(unsafe_binders): + ty::UnsafeBinder(_) => todo!(), + ty::Tuple(tys) if tys.is_empty() => AsyncDropGlueMorphology::Noop, ty::Adt(adt_def, _) if adt_def.is_manually_drop() => AsyncDropGlueMorphology::Noop, @@ -1522,7 +1527,7 @@ impl<'tcx> Ty<'tcx> { false } - ty::Foreign(_) | ty::CoroutineWitness(..) | ty::Error(_) => false, + ty::Foreign(_) | ty::CoroutineWitness(..) | ty::Error(_) | ty::UnsafeBinder(_) => false, } } @@ -1681,7 +1686,8 @@ pub fn needs_drop_components_with_async<'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::CoroutineWitness(..) => Ok(smallvec![ty]), + | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) => Ok(smallvec![ty]), } } diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index a93a146ec7c42..2dcba8c2f82c4 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -194,6 +194,9 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) sig_tys.skip_binder().inputs_and_output.iter().rev().map(|ty| ty.into()), ); } + ty::UnsafeBinder(bound_ty) => { + stack.push(bound_ty.skip_binder().into()); + } }, GenericArgKind::Lifetime(_) => {} GenericArgKind::Const(parent_ct) => match parent_ct.kind() { diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 0880364bfca00..d1b3a389e9e5d 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -161,6 +161,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) + | ty::UnsafeBinder(_) | ty::Alias(_, _) | ty::Param(_) | ty::Bound(_, _) @@ -200,6 +201,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> { | ty::Dynamic(_, _, _) | ty::CoroutineWitness(..) | ty::Never + | ty::UnsafeBinder(_) | ty::Alias(_, _) | ty::Param(_) | ty::Bound(_, _) diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 711cf2edc4627..51af77778af82 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -944,7 +944,8 @@ fn try_write_constant<'tcx>( | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) - | ty::Dynamic(..) => throw_machine_stop_str!("unsupported type"), + | ty::Dynamic(..) + | ty::UnsafeBinder(_) => throw_machine_stop_str!("unsupported type"), ty::Error(_) | ty::Infer(..) | ty::CoroutineWitness(..) => bug!(), } diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 7fb421dea0c74..e5a183bc75ce5 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -285,7 +285,9 @@ fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { | ty::Placeholder(_) | ty::Infer(_) | ty::Slice(_) - | ty::Array(_, _) => None, + | ty::Array(_, _) + | ty::UnsafeBinder(_) => None, + ty::Adt(adt_def, _) => { let did = adt_def.did(); let try_local_did_span = |did: DefId| { diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 2f7301d8fe515..8a54a4ece983e 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -378,6 +378,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { | ty::Pat(_, _) | ty::FnDef(_, _) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Dynamic(_, _, _) | ty::Closure(..) | ty::CoroutineClosure(..) diff --git a/compiler/rustc_next_trait_solver/src/coherence.rs b/compiler/rustc_next_trait_solver/src/coherence.rs index 2461ef0c0df57..408742747c2a1 100644 --- a/compiler/rustc_next_trait_solver/src/coherence.rs +++ b/compiler/rustc_next_trait_solver/src/coherence.rs @@ -339,7 +339,9 @@ where | ty::Slice(..) | ty::RawPtr(..) | ty::Never - | ty::Tuple(..) => self.found_non_local_ty(ty), + | ty::Tuple(..) + // FIXME(unsafe_binders): Non-local? + | ty::UnsafeBinder(_) => self.found_non_local_ty(ty), ty::Param(..) => panic!("unexpected ty param"), diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 02f6439b77fb7..63432dc199b98 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -545,6 +545,7 @@ where | ty::Ref(_, _, _) | ty::FnDef(_, _) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Dynamic(..) | ty::Closure(..) | ty::CoroutineClosure(..) @@ -634,6 +635,7 @@ where | ty::Ref(_, _, _) | ty::FnDef(_, _) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Alias(..) | ty::Closure(..) | ty::CoroutineClosure(..) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 05ce61bc0678f..7da4f5e010754 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -83,6 +83,8 @@ where .map(|bty| bty.instantiate(cx, args)) .collect()), + ty::UnsafeBinder(bound_ty) => Ok(vec![bound_ty.into()]), + // For `PhantomData`, we pass `T`. ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]), @@ -144,6 +146,8 @@ where panic!("unexpected type `{ty:?}`") } + ty::UnsafeBinder(bound_ty) => Ok(vec![bound_ty.into()]), + // impl Sized for () // impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1 ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |ty| vec![ty::Binder::dummy(ty)])), @@ -239,6 +243,8 @@ where } }, + ty::UnsafeBinder(_) => Err(NoSolution), + // impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types ty::CoroutineWitness(def_id, args) => Ok(ecx .cx() @@ -374,6 +380,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable( | ty::Param(_) | ty::Placeholder(..) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) - | ty::Error(_) => return Err(NoSolution), + | ty::Error(_) + | ty::UnsafeBinder(_) => return Err(NoSolution), ty::Bound(..) | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { @@ -764,6 +773,10 @@ pub(in crate::solve) fn const_conditions_for_destruct( | ty::Coroutine(_, _) | ty::CoroutineWitness(_, _) => Err(NoSolution), + // FIXME(unsafe_binders): Unsafe binders could implement `~const Drop` + // if their inner type implements it. + ty::UnsafeBinder(_) => Err(NoSolution), + ty::Dynamic(..) | ty::Param(_) | ty::Alias(..) | ty::Placeholder(_) | ty::Foreign(_) => { Err(NoSolution) } diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index b886719222510..f5ecfea540858 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -619,6 +619,11 @@ where Some(tail_ty) => Ty::new_projection(cx, metadata_def_id, [tail_ty]), }, + ty::UnsafeBinder(_) => { + // FIXME(unsafe_binder): Figure out how to handle pointee for unsafe binders. + todo!() + } + ty::Infer( ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_), ) @@ -822,6 +827,11 @@ where | ty::Tuple(_) | ty::Error(_) => self_ty.discriminant_ty(ecx.cx()), + ty::UnsafeBinder(_) => { + // FIXME(unsafe_binders): instantiate this with placeholders?? i guess?? + todo!("discr subgoal...") + } + // We do not call `Ty::discriminant_ty` on alias, param, or placeholder // types, which return `::Discriminant` // (or ICE in the case of placeholders). Projecting a type to itself @@ -869,6 +879,11 @@ where | ty::Tuple(_) | ty::Error(_) => self_ty.async_destructor_ty(ecx.cx()), + ty::UnsafeBinder(_) => { + // FIXME(unsafe_binders): Instantiate the binder with placeholders I guess. + todo!() + } + // We do not call `Ty::async_destructor_ty` on alias, param, or placeholder // types, which return `::AsyncDestructor` // (or ICE in the case of placeholders). Projecting a type to itself diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 886cdec034552..d68fca608299a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1100,7 +1100,8 @@ where | ty::CoroutineWitness(..) | ty::Never | ty::Tuple(_) - | ty::Adt(_, _) => { + | ty::Adt(_, _) + | ty::UnsafeBinder(_) => { let mut disqualifying_impl = None; self.cx().for_each_relevant_impl( goal.predicate.def_id(), diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 009d817a1a93b..ae991e3ce4030 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -415,6 +415,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(_, _) + | ty::UnsafeBinder(_) | ty::Alias(_, _) | ty::Param(_) | ty::Error(_) => ConstructorSet::Unlistable, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index c50c9007a010d..9ae2d981ab060 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -285,6 +285,7 @@ where | ty::Ref(..) | ty::Pat(..) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Param(..) | ty::Bound(..) | ty::Error(_) diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs index 34e1c31683a22..895259d52a7fd 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs @@ -621,6 +621,11 @@ pub(crate) fn encode_ty<'tcx>( typeid.push_str(&s); } + // FIXME(unsafe_binders): Implement this. + ty::UnsafeBinder(_) => { + todo!() + } + // Trait types ty::Dynamic(predicates, region, kind) => { // u3dynIE, where is , as diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 9c01bd0435346..9c6186d688284 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -64,7 +64,8 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { | ty::Pat(..) | ty::Slice(..) | ty::Str - | ty::Tuple(..) => t.super_fold_with(self), + | ty::Tuple(..) + | ty::UnsafeBinder(_) => t.super_fold_with(self), ty::Bool => { if self.options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index a4f61313001f1..e15dad78c693f 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -356,6 +356,8 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { ty::FnPtr(sig_tys, hdr) => { TyKind::RigidTy(RigidTy::FnPtr(sig_tys.with(*hdr).stable(tables))) } + // FIXME(unsafe_binders): + ty::UnsafeBinder(_) => todo!(), ty::Dynamic(existential_predicates, region, dyn_kind) => { TyKind::RigidTy(RigidTy::Dynamic( existential_predicates diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 123e4b1f01f26..65e515c0c2df6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2149,6 +2149,7 @@ symbols! { unwrap, unwrap_binder, unwrap_or, + unwrap_unsafe_binder, use_extern_macros, use_nested_groups, used, diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index a801b3e53a1a8..0ca47eba5e81e 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -466,6 +466,9 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { })?; } + // FIXME(unsafe_binder): + ty::UnsafeBinder(..) => todo!(), + ty::Dynamic(predicates, r, kind) => { self.push(match kind { ty::Dyn => "D", diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d41f8f46c1779..885b606326c54 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1532,6 +1532,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ty::CoroutineWitness(..) => Some(20), ty::CoroutineClosure(..) => Some(21), ty::Pat(..) => Some(22), + ty::UnsafeBinder(..) => Some(23), ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None, } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 4bccd3450bc6e..54407d17dcf0f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1047,6 +1047,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // Integers and floats always have `u8` as their discriminant. | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true, + ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), + // type parameters, opaques, and unnormalized projections don't have // a known discriminant and may need to be normalized further or rely // on param env for discriminant projections @@ -1072,6 +1074,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Ref(..) | ty::FnDef(..) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Dynamic(..) | ty::Closure(..) | ty::CoroutineClosure(..) @@ -1163,6 +1166,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( true } + ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binder)"), + // FIXME(compiler-errors): are Bound and Placeholder types ever known sized? ty::Param(_) | ty::Alias(..) diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 1d3e8d43af743..4004e354dc189 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -83,7 +83,8 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { | ty::Placeholder(..) | ty::Infer(_) | ty::Bound(..) - | ty::Coroutine(..) => false, + | ty::Coroutine(..) + | ty::UnsafeBinder(_) => false, } } @@ -336,6 +337,11 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( constraints.dtorck_types.push(ty); } + // Can't instantiate binder here. + ty::UnsafeBinder(_) => { + constraints.dtorck_types.push(ty); + } + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => { // By the time this code runs, all type variables ought to // be fully resolved. diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 5e27fd4378976..d6ac4baf8ad7c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -619,7 +619,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { continue; } - match obligation.self_ty().skip_binder().kind() { + let self_ty = obligation.self_ty().skip_binder(); + match self_ty.kind() { // Fast path to avoid evaluating an obligation that trivially holds. // There may be more bounds, but these are checked by the regular path. ty::FnPtr(..) => return false, @@ -651,6 +652,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(_, _) | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(_) | ty::Error(_) => return true, @@ -794,7 +796,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Coroutine(..) | ty::Never | ty::Tuple(_) - | ty::CoroutineWitness(..) => { + | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) => { // Only consider auto impls of unsafe traits when there are // no unsafe fields. if self.tcx().trait_is_unsafe(def_id) && self_ty.has_unsafe_fields() { @@ -1176,6 +1179,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::FnDef(_, _) | ty::Pat(_, _) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Dynamic(_, _, _) | ty::Closure(..) | ty::CoroutineClosure(..) @@ -1220,6 +1224,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::CoroutineWitness(..) + | ty::UnsafeBinder(_) | ty::Never | ty::Tuple(..) | ty::Alias(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0462b1d9ee777..7857ed95cc716 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2095,6 +2095,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } + // FIXME(unsafe_binders): This binder needs to be squashed + ty::UnsafeBinder(binder_ty) => Where(binder_ty.map_bound(|ty| vec![ty])), + ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None, ty::Infer(ty::TyVar(_)) => Ambiguous, @@ -2133,6 +2136,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> { None } + // FIXME(unsafe_binder): Should we conditionally + // (i.e. universally) implement copy/clone? + ty::UnsafeBinder(_) => None, + ty::Dynamic(..) | ty::Str | ty::Slice(..) @@ -2285,6 +2292,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | ty::Never | ty::Char => ty::Binder::dummy(Vec::new()), + // FIXME(unsafe_binders): Squash the double binder for now, I guess. + ty::UnsafeBinder(_) => return Err(SelectionError::Unimplemented), + // Treat this like `struct str([u8]);` ty::Str => ty::Binder::dummy(vec![Ty::new_slice(self.tcx(), self.tcx().types.u8)]), diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index c95b1641d1ffe..9d32eb0538606 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -828,6 +828,9 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { // Let the visitor iterate into the argument/return // types appearing in the fn signature. } + ty::UnsafeBinder(_) => { + // FIXME(unsafe_binders): We should also recurse into the binder here. + } ty::Dynamic(data, r, _) => { // WfObject diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index eb30169a7d918..fc76a86f79772 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -49,7 +49,8 @@ fn resolve_instance_raw<'tcx>( | ty::Adt(..) | ty::Dynamic(..) | ty::Array(..) - | ty::Slice(..) => {} + | ty::Slice(..) + | ty::UnsafeBinder(..) => {} // Drop shims can only be built from ADTs. _ => return Ok(None), } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index a3b2ed07d4b33..9f138cf1275d2 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -666,6 +666,11 @@ fn layout_of_uncached<'tcx>( tcx.mk_layout(layout) } + ty::UnsafeBinder(bound_ty) => { + let ty = tcx.instantiate_bound_regions_with_erased(bound_ty.into()); + cx.layout_of(ty)?.layout + } + // Types with no meaningful known layout. ty::Alias(..) => { // NOTE(eddyb) `layout_of` query should've normalized these away, diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 1c85eb2a86130..80de7e20951a7 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -202,6 +202,11 @@ where } } + ty::UnsafeBinder(bound_ty) => { + let ty = self.tcx.instantiate_bound_regions_with_erased(bound_ty.into()); + queue_type(self, ty); + } + _ if tcx.type_is_copy_modulo_regions(self.typing_env, component) => {} ty::Closure(_, args) => { diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 774f066025882..7eed32e3a3366 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -37,6 +37,8 @@ fn sized_constraint_for_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option None, + UnsafeBinder(_) => todo!(), + // these are never sized Str | Slice(..) | Dynamic(_, _, ty::Dyn) | Foreign(..) => Some(ty), diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index c06a578d8ec70..47447af22158d 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -6,8 +6,6 @@ use std::ops::{ControlFlow, Deref}; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; -#[cfg(feature = "nightly")] -use rustc_serialize::Decodable; use tracing::instrument; use crate::data_structures::SsoHashSet; @@ -69,14 +67,14 @@ macro_rules! impl_binder_encode_decode { self.as_ref().skip_binder().encode(e); } } - impl> Decodable for ty::Binder + impl> rustc_serialize::Decodable for ty::Binder where $t: TypeVisitable + rustc_serialize::Decodable, I::BoundVarKinds: rustc_serialize::Decodable, { fn decode(decoder: &mut D) -> Self { - let bound_vars = Decodable::decode(decoder); - ty::Binder::bind_with_vars(<$t>::decode(decoder), bound_vars) + let bound_vars = rustc_serialize::Decodable::decode(decoder); + ty::Binder::bind_with_vars(rustc_serialize::Decodable::decode(decoder), bound_vars) } } )* diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs index 81c8a7d4bfa49..9b3ff14d507ac 100644 --- a/compiler/rustc_type_ir/src/fast_reject.rs +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -41,6 +41,7 @@ pub enum SimplifiedType { Coroutine(DefId), CoroutineWitness(DefId), Function(usize), + UnsafeBinder, Placeholder, Error, } @@ -138,6 +139,7 @@ pub fn simplify_type( ty::FnPtr(sig_tys, _hdr) => { Some(SimplifiedType::Function(sig_tys.skip_binder().inputs().len())) } + ty::UnsafeBinder(_) => Some(SimplifiedType::UnsafeBinder), ty::Placeholder(..) => Some(SimplifiedType::Placeholder), ty::Param(_) => match treat_params { TreatParams::AsRigid => Some(SimplifiedType::Placeholder), @@ -290,7 +292,8 @@ impl {} + | ty::Placeholder(_) + | ty::UnsafeBinder(_) => {} }; // The type system needs to support exponentially large types @@ -447,6 +450,13 @@ impl match rhs.kind() { + ty::UnsafeBinder(rhs_ty) => { + self.types_may_unify(lhs_ty.skip_binder(), rhs_ty.skip_binder()) + } + _ => false, + }, + ty::Error(..) => true, } } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 2db40accda39b..872cf6680185b 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -112,6 +112,8 @@ pub trait Ty>: fn new_pat(interner: I, ty: Self, pat: I::Pat) -> Self; + fn new_unsafe_binder(interner: I, ty: ty::Binder) -> Self; + fn tuple_fields(self) -> I::Tys; fn to_opt_closure_kind(self) -> Option; @@ -185,6 +187,7 @@ pub trait Ty>: | ty::Ref(_, _, _) | ty::FnDef(_, _) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Dynamic(_, _, _) | ty::Closure(_, _) | ty::CoroutineClosure(_, _) diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index 0e94e989b978e..c26e211a79402 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -202,6 +202,7 @@ impl TypeVisitor for OutlivesCollector<'_, I> { | ty::RawPtr(_, _) | ty::Ref(_, _, _) | ty::FnPtr(..) + | ty::UnsafeBinder(_) | ty::Dynamic(_, _, _) | ty::Tuple(_) => { ty.super_visit_with(self); diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 0b013b2017f12..e628b66d2f086 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -549,6 +549,10 @@ pub fn structurally_relate_tys>( Ok(Ty::new_pat(cx, ty, pat)) } + (ty::UnsafeBinder(a_binder), ty::UnsafeBinder(b_binder)) => { + Ok(Ty::new_unsafe_binder(cx, relation.binders(*a_binder, *b_binder)?)) + } + _ => Err(TypeError::Sorts(ExpectedFound::new(a, b))), } } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 033fcdb6c0339..d2d5a1c00534f 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -1,4 +1,5 @@ use std::fmt; +use std::ops::Deref; use derive_where::derive_where; use rustc_ast_ir::Mutability; @@ -13,7 +14,8 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen use self::TyKind::*; pub use self::closure::*; use crate::inherent::*; -use crate::{self as ty, DebruijnIndex, Interner}; +use crate::visit::TypeVisitable; +use crate::{self as ty, DebruijnIndex, Interner, TyDecoder, TyEncoder}; mod closure; @@ -150,6 +152,13 @@ pub enum TyKind { /// worth the mild inconvenience. FnPtr(ty::Binder>, FnHeader), + /// An unsafe binder type. + /// + /// A higher-ranked type used to represent a type which has had some of its + /// lifetimes erased. This can be used to represent types in positions where + /// a lifetime is literally inexpressible, such as self-referential types. + UnsafeBinder(UnsafeBinderInner), + /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`. Dynamic(I::BoundExistentialPredicates, I::Region, DynKind), @@ -287,6 +296,8 @@ impl fmt::Debug for TyKind { Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t), FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(), FnPtr(sig_tys, hdr) => write!(f, "{:?}", sig_tys.with(*hdr)), + // FIXME(unsafe_binder): print this like `unsafe<'a> T<'a>`. + UnsafeBinder(binder) => write!(f, "{:?}", binder), Dynamic(p, r, repr) => match repr { DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"), DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"), @@ -964,6 +975,66 @@ impl fmt::Debug for FnSig { } } +// FIXME: this is a distinct type because we need to define `Encode`/`Decode` +// impls in this crate for `Binder`. +#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +pub struct UnsafeBinderInner(ty::Binder); + +impl From> for UnsafeBinderInner { + fn from(value: ty::Binder) -> Self { + UnsafeBinderInner(value) + } +} + +impl From> for ty::Binder { + fn from(value: UnsafeBinderInner) -> Self { + value.0 + } +} + +impl fmt::Debug for UnsafeBinderInner { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Deref for UnsafeBinderInner { + type Target = ty::Binder; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[cfg(feature = "nightly")] +impl> rustc_serialize::Encodable for UnsafeBinderInner +where + I::Ty: rustc_serialize::Encodable, + I::BoundVarKinds: rustc_serialize::Encodable, +{ + fn encode(&self, e: &mut E) { + self.bound_vars().encode(e); + self.as_ref().skip_binder().encode(e); + } +} + +#[cfg(feature = "nightly")] +impl> rustc_serialize::Decodable for UnsafeBinderInner +where + I::Ty: TypeVisitable + rustc_serialize::Decodable, + I::BoundVarKinds: rustc_serialize::Decodable, +{ + fn decode(decoder: &mut D) -> Self { + let bound_vars = rustc_serialize::Decodable::decode(decoder); + UnsafeBinderInner(ty::Binder::bind_with_vars( + rustc_serialize::Decodable::decode(decoder), + bound_vars, + )) + } +} + // This is just a `FnSig` without the `FnHeader` fields. #[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 9d0c0f687c706..4d46f0e75c84a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2255,12 +2255,14 @@ pub(crate) fn clean_middle_ty<'tcx>( } } + ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binders)"), ty::Closure(..) => panic!("Closure"), ty::CoroutineClosure(..) => panic!("CoroutineClosure"), ty::Coroutine(..) => panic!("Coroutine"), ty::Placeholder(..) => panic!("Placeholder"), ty::CoroutineWitness(..) => panic!("CoroutineWitness"), ty::Infer(..) => panic!("Infer"), + ty::Error(_) => FatalError.raise(), } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c9d1ceb0a91a9..3c1d0c35befa6 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -559,6 +559,7 @@ impl<'tcx> LinkCollector<'_, 'tcx> { | ty::Coroutine(..) | ty::CoroutineWitness(..) | ty::Dynamic(..) + | ty::UnsafeBinder(_) | ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index e3959903fddc9..821312a9e401c 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -877,7 +877,8 @@ impl TyCoercionStability { | ty::CoroutineClosure(..) | ty::Never | ty::Tuple(_) - | ty::Alias(ty::Projection, _) => Self::Deref, + | ty::Alias(ty::Projection, _) + | ty::UnsafeBinder(_) => Self::Deref, }; } } diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 71499b1293a51..afceeec22726a 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -677,6 +677,9 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( ExprKind::Type(e, _) => { helper(typeck, consume, e, f)?; }, + ExprKind::UnsafeBinderCast(_, e, _) => { + helper(typeck, consume, e, f)?; + }, // Either drops temporaries, jumps out of the current expression, or has no sub expression. ExprKind::DropTemps(_) @@ -694,7 +697,6 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( | ExprKind::Continue(_) | ExprKind::InlineAsm(_) | ExprKind::OffsetOf(..) - | ExprKind::UnsafeBinderCast(..) | ExprKind::Err(_) => (), } ControlFlow::Continue(()) diff --git a/tests/debuginfo/function-names.rs b/tests/debuginfo/function-names.rs index d9b61e7362153..c51884451e56f 100644 --- a/tests/debuginfo/function-names.rs +++ b/tests/debuginfo/function-names.rs @@ -37,7 +37,7 @@ // Const generic parameter // gdb-command:info functions -q function_names::const_generic_fn.* // gdb-check:[...]static fn function_names::const_generic_fn_bool(); -// gdb-check:[...]static fn function_names::const_generic_fn_non_int<{CONST#a70c39591cb5f53d}>(); +// gdb-check:[...]static fn function_names::const_generic_fn_non_int<{CONST#ffa3db4ca1d52dce}>(); // gdb-check:[...]static fn function_names::const_generic_fn_signed_int<-7>(); // gdb-check:[...]static fn function_names::const_generic_fn_unsigned_int<14>(); diff --git a/tests/ui/feature-gates/feature-gate-auto-traits.rs b/tests/ui/feature-gates/feature-gate-auto-traits.rs index 80cfa9cee8959..aab9e784fe9d7 100644 --- a/tests/ui/feature-gates/feature-gate-auto-traits.rs +++ b/tests/ui/feature-gates/feature-gate-auto-traits.rs @@ -7,6 +7,6 @@ auto trait AutoDummyTrait {} //~^ ERROR auto traits are experimental and possibly buggy impl !AutoDummyTrait for DummyStruct {} -//~^ ERROR negative trait bounds are not yet fully implemented; use marker types for now +//~^ ERROR negative trait bounds are not fully implemented; use marker types for now fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-auto-traits.stderr b/tests/ui/feature-gates/feature-gate-auto-traits.stderr index 139229ca809b2..8fa5168b2d041 100644 --- a/tests/ui/feature-gates/feature-gate-auto-traits.stderr +++ b/tests/ui/feature-gates/feature-gate-auto-traits.stderr @@ -8,7 +8,7 @@ LL | auto trait AutoDummyTrait {} = help: add `#![feature(auto_traits)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now +error[E0658]: negative trait bounds are not fully implemented; use marker types for now --> $DIR/feature-gate-auto-traits.rs:9:6 | LL | impl !AutoDummyTrait for DummyStruct {} diff --git a/tests/ui/symbol-names/basic.legacy.stderr b/tests/ui/symbol-names/basic.legacy.stderr index 6ce0ae09195d2..2f26c0cf0d3b3 100644 --- a/tests/ui/symbol-names/basic.legacy.stderr +++ b/tests/ui/symbol-names/basic.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN5basic4main17had874e876c8b1028E) +error: symbol-name(_ZN5basic4main17h144191e1523a280eE) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(basic::main::had874e876c8b1028) +error: demangling(basic::main::h144191e1523a280e) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] diff --git a/tests/ui/symbol-names/issue-60925.legacy.stderr b/tests/ui/symbol-names/issue-60925.legacy.stderr index cc4eec470fb00..cc79cc8b5169e 100644 --- a/tests/ui/symbol-names/issue-60925.legacy.stderr +++ b/tests/ui/symbol-names/issue-60925.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17haf0d0ad2255e29c6E) +error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h71f988fda3b6b180E) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(issue_60925::foo::Foo::foo::haf0d0ad2255e29c6) +error: demangling(issue_60925::foo::Foo::foo::h71f988fda3b6b180) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] diff --git a/tests/ui/traits/negative-impls/feature-gate-negative_impls.rs b/tests/ui/traits/negative-impls/feature-gate-negative_impls.rs index 683fd6db6f29d..8d3f6ff6d78c7 100644 --- a/tests/ui/traits/negative-impls/feature-gate-negative_impls.rs +++ b/tests/ui/traits/negative-impls/feature-gate-negative_impls.rs @@ -1,3 +1,3 @@ trait MyTrait {} -impl !MyTrait for u32 {} //~ ERROR negative trait bounds are not yet fully implemented +impl !MyTrait for u32 {} //~ ERROR negative trait bounds are not fully implemented fn main() {} diff --git a/tests/ui/traits/negative-impls/feature-gate-negative_impls.stderr b/tests/ui/traits/negative-impls/feature-gate-negative_impls.stderr index f3dee114116ca..1777dfcc993f1 100644 --- a/tests/ui/traits/negative-impls/feature-gate-negative_impls.stderr +++ b/tests/ui/traits/negative-impls/feature-gate-negative_impls.stderr @@ -1,4 +1,4 @@ -error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now +error[E0658]: negative trait bounds are not fully implemented; use marker types for now --> $DIR/feature-gate-negative_impls.rs:2:6 | LL | impl !MyTrait for u32 {} diff --git a/tests/ui/unsafe-binders/expr.rs b/tests/ui/unsafe-binders/expr.rs index d8c4c2df2cd95..0fe68751f0ae8 100644 --- a/tests/ui/unsafe-binders/expr.rs +++ b/tests/ui/unsafe-binders/expr.rs @@ -4,10 +4,11 @@ use std::unsafe_binder::{wrap_binder, unwrap_binder}; fn main() { + unsafe { let x = 1; - let binder: unsafe<'a> &'a i32 = wrap_binder!(x); - //~^ ERROR unsafe binders are not yet implemented - //~| ERROR unsafe binders are not yet implemented - let rx = *unwrap_binder!(binder); - //~^ ERROR unsafe binders are not yet implemented + let binder: unsafe<'a> &'a i32 = wrap_binder!(&x); + //~^ ERROR unsafe binder casts are not fully implemented + let rx = *unwrap_binder!(binder); + //~^ ERROR unsafe binder casts are not fully implemented + } } diff --git a/tests/ui/unsafe-binders/expr.stderr b/tests/ui/unsafe-binders/expr.stderr index 26fae1958b0a9..78a288e10a3c0 100644 --- a/tests/ui/unsafe-binders/expr.stderr +++ b/tests/ui/unsafe-binders/expr.stderr @@ -7,23 +7,17 @@ LL | #![feature(unsafe_binders)] = note: see issue #130516 for more information = note: `#[warn(incomplete_features)]` on by default -error: unsafe binders are not yet implemented - --> $DIR/expr.rs:8:17 +error: unsafe binder casts are not fully implemented + --> $DIR/expr.rs:9:55 | -LL | let binder: unsafe<'a> &'a i32 = wrap_binder!(x); - | ^^^^^^^^^^^^^^^^^^ +LL | let binder: unsafe<'a> &'a i32 = wrap_binder!(&x); + | ^^ -error: unsafe binders are not yet implemented - --> $DIR/expr.rs:8:51 +error: unsafe binder casts are not fully implemented + --> $DIR/expr.rs:11:34 | -LL | let binder: unsafe<'a> &'a i32 = wrap_binder!(x); - | ^ +LL | let rx = *unwrap_binder!(binder); + | ^^^^^^ -error: unsafe binders are not yet implemented - --> $DIR/expr.rs:11:30 - | -LL | let rx = *unwrap_binder!(binder); - | ^^^^^^ - -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/unsafe-binders/lifetime-resolution.rs b/tests/ui/unsafe-binders/lifetime-resolution.rs index aebed9599d400..b352acfadf284 100644 --- a/tests/ui/unsafe-binders/lifetime-resolution.rs +++ b/tests/ui/unsafe-binders/lifetime-resolution.rs @@ -3,16 +3,13 @@ fn foo<'a>() { let good: unsafe<'b> &'a &'b (); - //~^ ERROR unsafe binders are not yet implemented let missing: unsafe<> &'missing (); - //~^ ERROR unsafe binders are not yet implemented - //~| ERROR use of undeclared lifetime name `'missing` + //~^ ERROR use of undeclared lifetime name `'missing` fn inner<'b>() { let outer: unsafe<> &'a &'b (); - //~^ ERROR unsafe binders are not yet implemented - //~| can't use generic parameters from outer item + //~^ can't use generic parameters from outer item } } diff --git a/tests/ui/unsafe-binders/lifetime-resolution.stderr b/tests/ui/unsafe-binders/lifetime-resolution.stderr index 7a8ce929df136..69660c271bfc9 100644 --- a/tests/ui/unsafe-binders/lifetime-resolution.stderr +++ b/tests/ui/unsafe-binders/lifetime-resolution.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'missing` - --> $DIR/lifetime-resolution.rs:8:28 + --> $DIR/lifetime-resolution.rs:7:28 | LL | let missing: unsafe<> &'missing (); | ^^^^^^^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn foo<'missing, 'a>() { | +++++++++ error[E0401]: can't use generic parameters from outer item - --> $DIR/lifetime-resolution.rs:13:30 + --> $DIR/lifetime-resolution.rs:11:30 | LL | fn foo<'a>() { | -- lifetime parameter from outer item @@ -41,25 +41,7 @@ LL | #![feature(unsafe_binders)] = note: see issue #130516 for more information = note: `#[warn(incomplete_features)]` on by default -error: unsafe binders are not yet implemented - --> $DIR/lifetime-resolution.rs:5:15 - | -LL | let good: unsafe<'b> &'a &'b (); - | ^^^^^^^^^^^^^^^^^^^^^ - -error: unsafe binders are not yet implemented - --> $DIR/lifetime-resolution.rs:8:18 - | -LL | let missing: unsafe<> &'missing (); - | ^^^^^^^^^^^^^^^^^^^^^ - -error: unsafe binders are not yet implemented - --> $DIR/lifetime-resolution.rs:13:20 - | -LL | let outer: unsafe<> &'a &'b (); - | ^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted Some errors have detailed explanations: E0261, E0401. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/unsafe-binders/mismatch.rs b/tests/ui/unsafe-binders/mismatch.rs new file mode 100644 index 0000000000000..731fe2d1ce9b9 --- /dev/null +++ b/tests/ui/unsafe-binders/mismatch.rs @@ -0,0 +1,43 @@ +#![feature(unsafe_binders)] +//~^ WARN the feature `unsafe_binders` is incomplete + +use std::unsafe_binder::{wrap_binder, unwrap_binder}; + +fn a() { + let _: unsafe<'a> &'a i32 = wrap_binder!(&()); + //~^ ERROR unsafe binder casts are not fully implemented + //~| ERROR mismatched types +} + +fn b() { + let _: i32 = wrap_binder!(&()); + //~^ ERROR unsafe binder casts are not fully implemented + //~| ERROR `wrap_binder!()` can only wrap into unsafe binder +} + +fn c() { + let y = 1; + unwrap_binder!(y); + //~^ ERROR unsafe binder casts are not fully implemented + //~| ERROR expected unsafe binder, found integer as input +} + +fn d() { + let unknown = Default::default(); + unwrap_binder!(unknown); + //~^ ERROR unsafe binder casts are not fully implemented + // FIXME(unsafe_binders): This should report ambiguity once we've removed + // the error above which taints the infcx. +} + +fn e() { + let x = wrap_binder!(&42); + //~^ ERROR unsafe binder casts are not fully implemented + // Currently, type inference doesn't flow backwards for unsafe binders. + // It could, perhaps, but that may cause even more surprising corners. + // FIXME(unsafe_binders): This should report ambiguity once we've removed + // the error above which taints the infcx. + let _: unsafe<'a> &'a i32 = x; +} + +fn main() {} diff --git a/tests/ui/unsafe-binders/mismatch.stderr b/tests/ui/unsafe-binders/mismatch.stderr new file mode 100644 index 0000000000000..a720e5dbdc1fe --- /dev/null +++ b/tests/ui/unsafe-binders/mismatch.stderr @@ -0,0 +1,68 @@ +warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/mismatch.rs:1:12 + | +LL | #![feature(unsafe_binders)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #130516 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: unsafe binder casts are not fully implemented + --> $DIR/mismatch.rs:7:46 + | +LL | let _: unsafe<'a> &'a i32 = wrap_binder!(&()); + | ^^^ + +error[E0308]: mismatched types + --> $DIR/mismatch.rs:7:46 + | +LL | let _: unsafe<'a> &'a i32 = wrap_binder!(&()); + | ^^^ expected `&i32`, found `&()` + | + = note: expected reference `&i32` + found reference `&()` + +error: unsafe binder casts are not fully implemented + --> $DIR/mismatch.rs:13:31 + | +LL | let _: i32 = wrap_binder!(&()); + | ^^^ + +error: `wrap_binder!()` can only wrap into unsafe binder, not `i32` + --> $DIR/mismatch.rs:13:18 + | +LL | let _: i32 = wrap_binder!(&()); + | ^^^^^^^^^^^^^^^^^ + | + = note: unsafe binders are the only valid output of wrap + = note: this error originates in the macro `wrap_binder` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe binder casts are not fully implemented + --> $DIR/mismatch.rs:20:20 + | +LL | unwrap_binder!(y); + | ^ + +error: expected unsafe binder, found integer as input of `unwrap_binder!()` + --> $DIR/mismatch.rs:20:20 + | +LL | unwrap_binder!(y); + | ^ + | + = note: only an unsafe binder type can be unwrapped + +error: unsafe binder casts are not fully implemented + --> $DIR/mismatch.rs:27:20 + | +LL | unwrap_binder!(unknown); + | ^^^^^^^ + +error: unsafe binder casts are not fully implemented + --> $DIR/mismatch.rs:34:26 + | +LL | let x = wrap_binder!(&42); + | ^^^ + +error: aborting due to 8 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/unsafe-binders/simple.rs b/tests/ui/unsafe-binders/simple.rs index cebff2cbfb86a..6172a9e1e7bb2 100644 --- a/tests/ui/unsafe-binders/simple.rs +++ b/tests/ui/unsafe-binders/simple.rs @@ -1,7 +1,8 @@ +//@ check-pass + #![feature(unsafe_binders)] //~^ WARN the feature `unsafe_binders` is incomplete fn main() { let x: unsafe<'a> &'a (); - //~^ ERROR unsafe binders are not yet implemented } diff --git a/tests/ui/unsafe-binders/simple.stderr b/tests/ui/unsafe-binders/simple.stderr index a21dbd00b4cbe..e4b82c12b066e 100644 --- a/tests/ui/unsafe-binders/simple.stderr +++ b/tests/ui/unsafe-binders/simple.stderr @@ -1,5 +1,5 @@ warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/simple.rs:1:12 + --> $DIR/simple.rs:3:12 | LL | #![feature(unsafe_binders)] | ^^^^^^^^^^^^^^ @@ -7,11 +7,5 @@ LL | #![feature(unsafe_binders)] = note: see issue #130516 for more information = note: `#[warn(incomplete_features)]` on by default -error: unsafe binders are not yet implemented - --> $DIR/simple.rs:5:12 - | -LL | let x: unsafe<'a> &'a (); - | ^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error; 1 warning emitted +warning: 1 warning emitted