Auto merge of #123147 - matthiaskrgr:rollup-2t5ot36, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #121943 (Clarify atomic bit validity)
 - #123075 (CFI: Fix drop and drop_in_place)
 - #123101 (Delegation: fix ICE on wrong `Self` instantiation)
 - #123130 (Load missing type of impl associated constant from trait definition)
 - #123133 (chore: fix some comments)
 - #123136 (Some wording improvement)
 - #123139 (`num::NonZero::get` can be 1 transmute instead of 2)
 - #123142 (Let nils know about changes to target docs)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-03-28 00:30:46 +00:00
commit d779a7a25f
43 changed files with 480 additions and 273 deletions

View File

@ -151,8 +151,8 @@ toolchain.
directory and uncomment the line `MSYS2_PATH_TYPE=inherit`.
You could install and use MSYS2's version of git instead with `pacman`,
however this is not recommended as it's excrutiatingly slow, and not frequently
tested for compatability.
however this is not recommended as it's excruciatingly slow, and not frequently
tested for compatibility.
3. Start a MINGW64 or MINGW32 shell (depending on whether you want 32-bit
or 64-bit Rust) either from your start menu, or by running `mingw64.exe`

View File

@ -75,7 +75,7 @@ pub(crate) struct FixupContext {
}
/// The default amount of fixing is minimal fixing. Fixups should be turned on
/// in a targetted fashion where needed.
/// in a targeted fashion where needed.
impl Default for FixupContext {
fn default() -> Self {
FixupContext {

View File

@ -592,7 +592,7 @@ fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Locatio
}
self.cx.borrowck_context.constraints.outlives_constraints.push(constraint)
}
// If the region is live at at least one location in the promoted MIR,
// If the region is live at least one location in the promoted MIR,
// then add a liveness constraint to the main MIR for this region
// at the location provided as an argument to this method
//

View File

@ -409,7 +409,7 @@ fn const_validate_mplace<'mir, 'tcx>(
}
};
ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)
// Instead of just reporting the `InterpError` via the usual machinery, we give a more targetted
// Instead of just reporting the `InterpError` via the usual machinery, we give a more targeted
// error about the validation failure.
.map_err(|error| report_validation_error(&ecx, error, alloc_id))?;
inner = true;

View File

@ -11,7 +11,7 @@
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Prohibit or lint against *bare* trait object types depending on the edition.
///
/// *Bare* trait object types are ones that aren't preceeded by the keyword `dyn`.
/// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`.
/// In edition 2021 and onward we emit a hard error for them.
pub(super) fn prohibit_or_lint_bare_trait_object_ty(
&self,

View File

@ -2212,6 +2212,17 @@ fn check_delegation_constraints(&self, sig_id: DefId, span: Span, emit: bool) ->
try_emit("delegation with early bound generics");
}
// There is no way to instantiate `Self` param for caller if
// 1. callee is a trait method
// 2. delegation item isn't an associative item
if let DefKind::AssocFn = self.tcx().def_kind(sig_id)
&& let DefKind::Fn = self.tcx().def_kind(self.item_def_id())
&& self.tcx().associated_item(sig_id).container
== ty::AssocItemContainer::TraitContainer
{
try_emit("delegation to a trait method from a free function");
}
if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes {
try_emit("delegation to async functions");
}

View File

@ -83,20 +83,6 @@ macro_rules! type_error_struct {
})
}
/// If this `DefId` is a "primary tables entry", returns
/// `Some((body_id, body_ty, fn_sig))`. Otherwise, returns `None`.
///
/// If this function returns `Some`, then `typeck_results(def_id)` will
/// succeed; if it returns `None`, then `typeck_results(def_id)` may or
/// may not succeed. In some cases where this function returns `None`
/// (notably closures), `typeck_results(def_id)` would wind up
/// redirecting to the owning function.
fn primary_body_of(
node: Node<'_>,
) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnSig<'_>>)> {
Some((node.body_id()?, node.ty(), node.fn_sig()))
}
fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
// Closures' typeck results come from their outermost function,
// as they are part of the same "inference environment".
@ -106,7 +92,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
}
if let Some(def_id) = def_id.as_local() {
primary_body_of(tcx.hir_node_by_def_id(def_id)).is_some()
tcx.hir_node_by_def_id(def_id).body_id().is_some()
} else {
false
}
@ -163,7 +149,7 @@ fn typeck_with_fallback<'tcx>(
let span = tcx.hir().span(id);
// Figure out what primary body this item has.
let (body_id, body_ty, fn_sig) = primary_body_of(node).unwrap_or_else(|| {
let body_id = node.body_id().unwrap_or_else(|| {
span_bug!(span, "can't type-check body of {:?}", def_id);
});
let body = tcx.hir().body(body_id);
@ -176,7 +162,7 @@ fn typeck_with_fallback<'tcx>(
}
let mut fcx = FnCtxt::new(&root_ctxt, param_env, def_id);
if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
if let Some(hir::FnSig { header, decl, .. }) = node.fn_sig() {
let fn_sig = if decl.output.get_infer_ret_ty().is_some() {
fcx.lowerer().lower_fn_ty(id, header.unsafety, header.abi, decl, None, None)
} else {
@ -191,42 +177,7 @@ fn typeck_with_fallback<'tcx>(
check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params);
} else {
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
}))
} else if let Node::AnonConst(_) = node {
match tcx.parent_hir_node(id) {
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. })
if anon_const.hir_id == id =>
{
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
}))
}
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
asm.operands.iter().find_map(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => {
// Inline assembly constants must be integers.
Some(fcx.next_int_var())
}
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => {
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span,
}))
}
_ => None,
})
}
_ => None,
}
} else {
None
};
let expected_type = infer_type_if_missing(&fcx, node);
let expected_type = expected_type.unwrap_or_else(fallback);
let expected_type = fcx.normalize(body.value.span, expected_type);
@ -296,6 +247,59 @@ fn typeck_with_fallback<'tcx>(
typeck_results
}
fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Option<Ty<'tcx>> {
let tcx = fcx.tcx;
let def_id = fcx.body_id;
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = node.ty() {
if let Some(item) = tcx.opt_associated_item(def_id.into())
&& let ty::AssocKind::Const = item.kind
&& let ty::ImplContainer = item.container
&& let Some(trait_item) = item.trait_item_def_id
{
let args =
tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args;
Some(tcx.type_of(trait_item).instantiate(tcx, args))
} else {
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
}))
}
} else if let Node::AnonConst(_) = node {
let id = tcx.local_def_id_to_hir_id(def_id);
match tcx.parent_hir_node(id) {
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), span, .. })
if anon_const.hir_id == id =>
{
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
}))
}
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), span, .. })
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), span, .. }) => {
asm.operands.iter().find_map(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => {
// Inline assembly constants must be integers.
Some(fcx.next_int_var())
}
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => {
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span,
}))
}
_ => None,
})
}
_ => None,
}
} else {
None
};
expected_type
}
/// When `check_fn` is invoked on a coroutine (i.e., a body that
/// includes yield), it returns back some information about the yield
/// points.

View File

@ -2768,7 +2768,7 @@ fn parse_for_head(&mut self) -> PResult<'a, (P<Pat>, P<Expr>)> {
};
return if self.token.kind == token::CloseDelim(Delimiter::Parenthesis) {
// We know for sure we have seen `for ($SOMETHING in $EXPR)`, so we recover the
// parser state and emit a targetted suggestion.
// parser state and emit a targeted suggestion.
let span = vec![start_span, self.token.span];
let right = self.prev_token.span.between(self.look_ahead(1, |t| t.span));
self.bump(); // )

View File

@ -1112,8 +1112,36 @@ pub fn typeid_for_instance<'tcx>(
mut instance: Instance<'tcx>,
options: TypeIdOptions,
) -> String {
if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
instance.args = strip_receiver_auto(tcx, instance.args)
if (matches!(instance.def, ty::InstanceDef::Virtual(..))
&& Some(instance.def_id()) == tcx.lang_items().drop_in_place_fn())
|| matches!(instance.def, ty::InstanceDef::DropGlue(..))
{
// Adjust the type ids of DropGlues
//
// DropGlues may have indirect calls to one or more given types drop function. Rust allows
// for types to be erased to any trait object and retains the drop function for the original
// type, which means at the indirect call sites in DropGlues, when typeid_for_fnabi is
// called a second time, it only has information after type erasure and it could be a call
// on any arbitrary trait object. Normalize them to a synthesized Drop trait object, both on
// declaration/definition, and during code generation at call sites so they have the same
// type id and match.
//
// FIXME(rcvalle): This allows a drop call on any trait object to call the drop function of
// any other type.
//
let def_id = tcx
.lang_items()
.drop_trait()
.unwrap_or_else(|| bug!("typeid_for_instance: couldn't get drop_trait lang item"));
let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef {
def_id: def_id,
args: List::empty(),
});
let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]);
let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn);
instance.args = tcx.mk_args_trait(self_ty, List::empty());
} else if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
instance.args = strip_receiver_auto(tcx, instance.args);
}
if let Some(impl_id) = tcx.impl_of_method(instance.def_id())

View File

@ -20,7 +20,15 @@
///
/// # Safety
///
/// Types implementing this trait must be primitves that are valid when zeroed.
/// Types implementing this trait must be primitives that are valid when zeroed.
///
/// The associated `Self::NonZeroInner` type must have the same size+align as `Self`,
/// but with a niche and bit validity making it so the following `transmutes` are sound:
///
/// - `Self::NonZeroInner` to `Option<Self::NonZeroInner>`
/// - `Option<Self::NonZeroInner>` to `Self`
///
/// (And, consequently, `Self::NonZeroInner` to `Self`.)
#[unstable(
feature = "nonzero_internals",
reason = "implementation detail which may disappear or be replaced at any time",
@ -434,17 +442,11 @@ pub const fn get(self) -> T {
// of some not-inlined function, LLVM don't have range metadata
// to understand that the value cannot be zero.
//
// SAFETY: `Self` is guaranteed to have the same layout as `Option<Self>`.
match unsafe { intrinsics::transmute_unchecked(self) } {
None => {
// SAFETY: `NonZero` is guaranteed to only contain non-zero values, so this is unreachable.
unsafe { intrinsics::unreachable() }
}
Some(Self(inner)) => {
// SAFETY: `T::NonZeroInner` is guaranteed to have the same layout as `T`.
unsafe { intrinsics::transmute_unchecked(inner) }
}
}
// For now, using the transmute `assume`s the range at runtime.
//
// SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity
// of `.0` is such that this transmute is sound.
unsafe { intrinsics::transmute_unchecked(self) }
}
}

View File

@ -806,7 +806,7 @@
//!
//! As a consequence, the struct *must not* be [`#[repr(packed)]`][packed].
//!
//! 3. *Structural Notice of Destruction.* You must uphold the the
//! 3. *Structural Notice of Destruction.* You must uphold the
//! [`Drop` guarantee][drop-guarantee]: once your struct is pinned, the struct's storage cannot
//! be re-used without calling the structurally-pinned fields' destructors, as well.
//!

View File

@ -243,7 +243,7 @@
/// A boolean type which can be safely shared between threads.
///
/// This type has the same in-memory representation as a [`bool`].
/// This type has the same size, alignment, and bit validity as a [`bool`].
///
/// **Note**: This type is only available on platforms that support atomic
/// loads and stores of `u8`.
@ -272,7 +272,7 @@ unsafe impl Sync for AtomicBool {}
/// A raw pointer type which can be safely shared between threads.
///
/// This type has the same in-memory representation as a `*mut T`.
/// This type has the same size and bit validity as a `*mut T`.
///
/// **Note**: This type is only available on platforms that support atomic
/// loads and stores of pointers. Its size depends on the target pointer's size.
@ -2121,7 +2121,7 @@ macro_rules! atomic_int {
$int_type:ident $atomic_type:ident) => {
/// An integer type which can be safely shared between threads.
///
/// This type has the same in-memory representation as the underlying
/// This type has the same size and bit validity as the underlying
/// integer type, [`
#[doc = $s_int_type]
/// `].

View File

@ -385,7 +385,7 @@ pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
/// See the [`OpenOptions::open`] function for more details.
///
/// See also [`std::fs::write()`][self::write] for a simple function to
/// create a file with a given data.
/// create a file with some given data.
///
/// # Examples
///
@ -1036,7 +1036,7 @@ pub fn truncate(&mut self, truncate: bool) -> &mut Self {
/// [`OpenOptions::append`] access must be used.
///
/// See also [`std::fs::write()`][self::write] for a simple function to
/// create a file with a given data.
/// create a file with some given data.
///
/// # Examples
///

View File

@ -0,0 +1,27 @@
// Verifies that type metadata identifiers for drop functions are emitted correctly.
//
//@ needs-sanitizer-cfi
//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
#![crate_type="lib"]
// CHECK-LABEL: define{{.*}}4core3ptr47drop_in_place$LT$dyn$u20$core..marker..Send$GT$
// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
// CHECK: call i1 @llvm.type.test(ptr {{%.+}}, metadata !"_ZTSFvPu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops4drop4Dropu6regionEE")
struct EmptyDrop;
// CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place$LT${{.*}}EmptyDrop$GT${{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
struct NonEmptyDrop;
impl Drop for NonEmptyDrop {
fn drop(&mut self) {}
// CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place$LT${{.*}}NonEmptyDrop$GT${{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
}
pub fn foo() {
let _ = Box::new(EmptyDrop) as Box<dyn Send>;
let _ = Box::new(NonEmptyDrop) as Box<dyn Send>;
}
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops4drop4Dropu6regionEE"}

View File

@ -29,6 +29,8 @@ impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b
trait Freeze { }
#[lang="drop_in_place"]
fn drop_in_place_fn<T>() { }
#[lang="drop"]
trait Drop { fn drop(&mut self); }
pub trait Trait1 {
fn foo(&self);

View File

@ -1,4 +1,4 @@
// Check that the targetted element has the expected styles.
// Check that the targeted element has the expected styles.
go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html#method.a_method"
show-text: true

View File

@ -0,0 +1,28 @@
//! Test that we compute the right type for associated constants
//! of impls, even if the type is missing. We know it from the trait
//! declaration after all.
trait Range {
const FIRST: u8;
const LAST: u8;
}
struct TwoDigits;
impl Range for TwoDigits {
const FIRST: = 10;
//~^ ERROR: missing type for `const` item
const LAST: u8 = 99;
}
const fn digits(x: u8) -> usize {
match x {
TwoDigits::FIRST..=TwoDigits::LAST => 0,
0..=9 | 100..=255 => panic!(),
}
}
const FOOMP: [(); {
digits(42)
}] = [];
fn main() {}

View File

@ -0,0 +1,8 @@
error: missing type for `const` item
--> $DIR/missing_assoc_const_type.rs:12:17
|
LL | const FIRST: = 10;
| ^ help: provide a type for the associated constant: `u8`
error: aborting due to 1 previous error

View File

@ -0,0 +1,21 @@
//! Test that we compute the right type for associated constants
//! of impls, even if the type is missing. We know it from the trait
//! declaration after all.
trait Range {
const FIRST: u8;
const LAST: u8;
}
struct TwoDigits;
impl Range for TwoDigits {
const FIRST: = 10;
//~^ ERROR: missing type
const LAST: u8 = 99;
}
const FOOMP: [(); {
TwoDigits::FIRST as usize
}] = [(); 10];
fn main() {}

View File

@ -0,0 +1,8 @@
error: missing type for `const` item
--> $DIR/missing_assoc_const_type2.rs:12:17
|
LL | const FIRST: = 10;
| ^ help: provide a type for the associated constant: `u8`
error: aborting due to 1 previous error

View File

@ -1,5 +1,5 @@
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]
trait Trait {
const C: u32 = 0;
@ -34,14 +34,6 @@ impl Trait for S {
reuse foo { &self.0 }
//~^ ERROR cannot find function `foo` in this scope
reuse F::foo { &self.0 }
//~^ ERROR cannot find function `foo` in `F`
//~| ERROR duplicate definitions with name `foo`
}
impl S {
reuse F::foo { &self.0 }
//~^ ERROR cannot find function `foo` in `F`
}
fn main() {}

View File

@ -25,18 +25,6 @@ LL | reuse <F as Trait>::baz;
| | help: there is an associated function with a similar name: `bar`
| not a member of trait `Trait`
error[E0201]: duplicate definitions with name `foo`:
--> $DIR/bad-resolve.rs:37:5
|
LL | fn foo(&self, x: i32) -> i32 { x }
| ---------------------------------- item in trait
...
LL | reuse foo { &self.0 }
| --------------------- previous definition here
LL |
LL | reuse F::foo { &self.0 }
| ^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition
error[E0423]: expected function, found associated constant `Trait::C`
--> $DIR/bad-resolve.rs:24:11
|
@ -66,27 +54,6 @@ error[E0425]: cannot find function `foo` in this scope
LL | reuse foo { &self.0 }
| ^^^ not found in this scope
error[E0425]: cannot find function `foo` in `F`
--> $DIR/bad-resolve.rs:37:14
|
LL | reuse F::foo { &self.0 }
| ^^^ not found in `F`
error[E0425]: cannot find function `foo` in `F`
--> $DIR/bad-resolve.rs:43:14
|
LL | reuse F::foo { &self.0 }
| ^^^ not found in `F`
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/bad-resolve.rs:1:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0046]: not all trait items implemented, missing: `Type`
--> $DIR/bad-resolve.rs:22:1
|
@ -96,7 +63,7 @@ LL | type Type;
LL | impl Trait for S {
| ^^^^^^^^^^^^^^^^ missing `Type` in implementation
error: aborting due to 11 previous errors; 1 warning emitted
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0046, E0201, E0324, E0407, E0423, E0425, E0575, E0576.
Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0575, E0576.
For more information about an error, try `rustc --explain E0046`.

View File

@ -1,5 +1,5 @@
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]
trait Trait {
fn foo(&self) -> u32 { 0 }

View File

@ -9,15 +9,6 @@ LL | reuse to_reuse::foo { self }
LL | reuse Trait::foo;
| ^^^^^^^^^^^^^^^^^ duplicate definition
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/duplicate-definition-inside-trait-impl.rs:1:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
error: aborting due to 1 previous error; 1 warning emitted
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0201`.

View File

@ -1,7 +1,7 @@
//@ run-pass
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]
trait ToReuse {
fn foo(&self, x: i32) -> i32 { x }

View File

@ -1,11 +0,0 @@
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/explicit-paths-in-traits-pass.rs:3:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: 1 warning emitted

View File

@ -1,7 +1,7 @@
//@ run-pass
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]
trait Trait {
fn bar(&self, x: i32) -> i32 { x }
@ -10,7 +10,6 @@ fn description(&self) -> &str {
}
fn static_method(x: i32) -> i32 { x }
fn static_method2(x: i32, y: i32) -> i32 { x + y }
fn baz<'a>(&self, x: &'a i32) -> &'a i32 { x }
}
struct F;
@ -29,11 +28,9 @@ impl Trait for S {
reuse Trait::description { &self.0 }
reuse <F as Trait>::static_method;
reuse <F as Trait>::static_method2 { S::static_method(self) }
reuse Trait::baz { &self.0 }
}
impl S {
reuse Trait::baz { &self.0 }
reuse <F as Trait>::static_method { to_reuse::foo(self) }
}
@ -49,16 +46,8 @@ fn main() {
assert_eq!(42, <S as Trait>::static_method(42));
assert_eq!(21, S::static_method2(10, 10));
reuse <S as Trait>::static_method;
reuse <S as Trait>::static_method2 { static_method(self) }
#[inline]
reuse to_reuse::foo;
assert_eq!(42, static_method(42));
assert_eq!(21, static_method2(10, 10));
assert_eq!(43, foo(42));
assert_eq!(15, zero_args());
let x: i32 = 15;
assert_eq!(&x, <S as Trait>::baz(&s, &x));
assert_eq!(&x, S::baz(&s, &x));
}

View File

@ -1,11 +0,0 @@
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/explicit-paths-pass.rs:3:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: 1 warning emitted

View File

@ -1,7 +1,7 @@
//@ run-pass
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]
mod to_reuse {
use crate::S;

View File

@ -1,11 +0,0 @@
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/explicit-paths-signature-pass.rs:3:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: 1 warning emitted

View File

@ -1,25 +1,84 @@
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]
trait Trait {
fn bar(&self) -> i32 { 42 }
fn foo1(&self, x: i32) -> i32 { x }
fn foo2(x: i32) -> i32 { x }
}
struct F;
impl Trait for F {}
struct S(F);
impl Trait for S {
reuse <F as Trait>::bar;
//~^ ERROR mismatched types
pub mod to_reuse {
pub fn foo3() {}
}
struct S2(F);
impl F {
fn foo4(&self) {}
}
impl Trait for S2 {
reuse <S2 as Trait>::bar { &self.0 }
//~^ ERROR mismatched types
mod fn_to_other {
use super::*;
reuse Trait::foo1;
//~^ ERROR delegation to a trait method from a free function is not supported yet
reuse <S as Trait>::foo2;
//~^ ERROR delegation to a trait method from a free function is not supported yet
reuse to_reuse::foo3;
reuse S::foo4;
//~^ ERROR cannot find function `foo4` in `S`
}
mod inherent_impl_assoc_fn_to_other {
use crate::*;
impl S {
reuse Trait::foo1 { &self.0 }
reuse <S as Trait>::foo2;
reuse to_reuse::foo3;
reuse F::foo4 { &self.0 }
//~^ ERROR cannot find function `foo4` in `F`
}
}
mod trait_impl_assoc_fn_to_other {
use crate::*;
impl Trait for S {
reuse Trait::foo1 { &self.0 }
reuse <F as Trait>::foo2;
reuse to_reuse::foo3;
//~^ ERROR method `foo3` is not a member of trait `Trait`
reuse F::foo4 { &self.0 }
//~^ ERROR method `foo4` is not a member of trait `Trait`
//~| ERROR cannot find function `foo4` in `F`
}
}
mod trait_assoc_fn_to_other {
use crate::*;
trait Trait2 : Trait {
reuse <F as Trait>::foo1 { self }
//~^ ERROR mismatched types
reuse <F as Trait>::foo2;
reuse to_reuse::foo3;
reuse F::foo4 { &F }
//~^ ERROR cannot find function `foo4` in `F`
}
}
mod type_mismatch {
use crate::*;
struct S2;
impl Trait for S {
//~^ ERROR conflicting implementations of trait `Trait` for type `S`
reuse <S2 as Trait>::foo1;
//~^ ERROR mismatched types
//~| ERROR the trait bound `S2: Trait` is not satisfied
}
}
fn main() {}

View File

@ -1,38 +1,129 @@
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/explicit-paths.rs:1:12
error[E0407]: method `foo3` is not a member of trait `Trait`
--> $DIR/explicit-paths.rs:51:9
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
LL | reuse to_reuse::foo3;
| ^^^^^^^^^^^^^^^^----^
| | |
| | help: there is an associated function with a similar name: `foo1`
| not a member of trait `Trait`
error[E0407]: method `foo4` is not a member of trait `Trait`
--> $DIR/explicit-paths.rs:53:9
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
LL | reuse F::foo4 { &self.0 }
| ^^^^^^^^^----^^^^^^^^^^^^
| | |
| | help: there is an associated function with a similar name: `foo1`
| not a member of trait `Trait`
error[E0425]: cannot find function `foo4` in `S`
--> $DIR/explicit-paths.rs:29:14
|
LL | reuse S::foo4;
| ^^^^ not found in `S`
error[E0425]: cannot find function `foo4` in `F`
--> $DIR/explicit-paths.rs:40:18
|
LL | reuse F::foo4 { &self.0 }
| ^^^^ not found in `F`
|
note: function `fn_to_other::foo4` exists but is inaccessible
--> $DIR/explicit-paths.rs:29:5
|
LL | reuse S::foo4;
| ^^^^^^^^^^^^^^ not accessible
error[E0425]: cannot find function `foo4` in `F`
--> $DIR/explicit-paths.rs:53:18
|
LL | reuse F::foo4 { &self.0 }
| ^^^^ not found in `F`
|
note: function `fn_to_other::foo4` exists but is inaccessible
--> $DIR/explicit-paths.rs:29:5
|
LL | reuse S::foo4;
| ^^^^^^^^^^^^^^ not accessible
error[E0425]: cannot find function `foo4` in `F`
--> $DIR/explicit-paths.rs:67:18
|
LL | reuse F::foo4 { &F }
| ^^^^ not found in `F`
|
note: function `fn_to_other::foo4` exists but is inaccessible
--> $DIR/explicit-paths.rs:29:5
|
LL | reuse S::foo4;
| ^^^^^^^^^^^^^^ not accessible
error[E0119]: conflicting implementations of trait `Trait` for type `S`
--> $DIR/explicit-paths.rs:76:5
|
LL | impl Trait for S {
| ---------------- first implementation here
...
LL | impl Trait for S {
| ^^^^^^^^^^^^^^^^ conflicting implementation for `S`
error: delegation to a trait method from a free function is not supported yet
--> $DIR/explicit-paths.rs:24:18
|
LL | fn foo1(&self, x: i32) -> i32 { x }
| ----------------------------- callee defined here
...
LL | reuse Trait::foo1;
| ^^^^
error: delegation to a trait method from a free function is not supported yet
--> $DIR/explicit-paths.rs:26:25
|
LL | fn foo2(x: i32) -> i32 { x }
| ---------------------- callee defined here
...
LL | reuse <S as Trait>::foo2;
| ^^^^
error[E0308]: mismatched types
--> $DIR/explicit-paths.rs:14:25
--> $DIR/explicit-paths.rs:63:36
|
LL | reuse <F as Trait>::bar;
| --------------^^^
| | |
| | expected `&F`, found `&S`
| arguments to this function are incorrect
LL | trait Trait2 : Trait {
| -------------------- found this type parameter
LL | reuse <F as Trait>::foo1 { self }
| ^^^^ expected `&F`, found `&Self`
|
= note: expected reference `&F`
found reference `&Self`
error[E0277]: the trait bound `S2: Trait` is not satisfied
--> $DIR/explicit-paths.rs:78:16
|
LL | reuse <S2 as Trait>::foo1;
| ^^ the trait `Trait` is not implemented for `S2`
|
= help: the following other types implement trait `Trait`:
F
S
error[E0308]: mismatched types
--> $DIR/explicit-paths.rs:78:30
|
LL | reuse <S2 as Trait>::foo1;
| ---------------^^^^
| | |
| | expected `&S2`, found `&S`
| arguments to this function are incorrect
|
= note: expected reference `&S2`
found reference `&S`
note: method defined here
--> $DIR/explicit-paths.rs:5:8
|
LL | fn bar(&self) -> i32 { 42 }
| ^^^ -----
LL | fn foo1(&self, x: i32) -> i32 { x }
| ^^^^ -----
error[E0308]: mismatched types
--> $DIR/explicit-paths.rs:21:32
|
LL | reuse <S2 as Trait>::bar { &self.0 }
| ^^^^^^^ expected `&S2`, found `&F`
|
= note: expected reference `&S2`
found reference `&F`
error: aborting due to 12 previous errors
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0119, E0277, E0308, E0407, E0425.
For more information about an error, try `rustc --explain E0119`.

View File

@ -1,6 +1,6 @@
#![feature(c_variadic)]
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]
mod generics {
trait GenericTrait<T> {

View File

@ -1,12 +1,3 @@
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/not-supported.rs:2:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
error: delegation with early bound generics is not supported yet
--> $DIR/not-supported.rs:16:29
|
@ -178,7 +169,7 @@ LL | pub reuse to_reuse2::foo;
LL | reuse to_reuse1::foo;
| ^^^
error: aborting due to 19 previous errors; 1 warning emitted
error: aborting due to 19 previous errors
Some errors have detailed explanations: E0049, E0195.
For more information about an error, try `rustc --explain E0049`.

View File

@ -2,7 +2,7 @@
#![feature(decl_macro)]
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]
macro_rules! reuse { {} => {} }

View File

@ -1,11 +0,0 @@
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/parse.rs:4:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: 1 warning emitted

View File

@ -1,7 +1,7 @@
//@ run-pass
#![feature(fn_delegation)]
//~^ WARN the feature `fn_delegation` is incomplete
#![allow(incomplete_features)]
mod to_reuse {
pub fn foo(x: i32) -> i32 { x }

View File

@ -1,12 +1,3 @@
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/target-expr-pass.rs:3:12
|
LL | #![feature(fn_delegation)]
| ^^^^^^^^^^^^^
|
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
= note: `#[warn(incomplete_features)]` on by default
warning: trait `Trait` is never used
--> $DIR/target-expr-pass.rs:17:7
|
@ -27,5 +18,5 @@ warning: struct `S` is never constructed
LL | struct S(F);
| ^
warning: 4 warnings emitted
warning: 3 warnings emitted

View File

@ -14,8 +14,9 @@ fn foo(x: i32) -> i32 { x }
fn bar<T: Default>(_: T) {
reuse Trait::static_method {
//~^ ERROR delegation with early bound generics is not supported yet
//~| ERROR mismatched types
//~^ ERROR delegation to a trait method from a free function is not supported yet
//~| ERROR delegation with early bound generics is not supported yet
//~| ERROR mismatched types
let _ = T::Default();
//~^ ERROR can't use generic parameters from outer item
}
@ -24,6 +25,7 @@ fn bar<T: Default>(_: T) {
fn main() {
let y = 0;
reuse <S as Trait>::static_method {
//~^ ERROR delegation to a trait method from a free function is not supported yet
let x = y;
//~^ ERROR can't capture dynamic environment in a fn item
foo(self);

View File

@ -1,5 +1,5 @@
error[E0401]: can't use generic parameters from outer item
--> $DIR/target-expr.rs:19:17
--> $DIR/target-expr.rs:20:17
|
LL | fn bar<T: Default>(_: T) {
| - type parameter from outer item
@ -10,7 +10,7 @@ LL | let _ = T::Default();
| ^^^^^^^^^^ use of generic parameter from outer item
error[E0434]: can't capture dynamic environment in a fn item
--> $DIR/target-expr.rs:27:17
--> $DIR/target-expr.rs:29:17
|
LL | let x = y;
| ^
@ -18,7 +18,7 @@ LL | let x = y;
= help: use the `|| { ... }` closure form instead
error[E0424]: expected value, found module `self`
--> $DIR/target-expr.rs:34:5
--> $DIR/target-expr.rs:36:5
|
LL | fn main() {
| ---- this function can't have a `self` parameter
@ -27,13 +27,13 @@ LL | self.0;
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
error[E0425]: cannot find value `x` in this scope
--> $DIR/target-expr.rs:36:13
--> $DIR/target-expr.rs:38:13
|
LL | let z = x;
| ^
|
help: the binding `x` is available in a different scope in the same function
--> $DIR/target-expr.rs:27:13
--> $DIR/target-expr.rs:29:13
|
LL | let x = y;
| ^
@ -47,6 +47,24 @@ LL | fn static_method(x: i32) -> i32 { x }
LL | reuse Trait::static_method {
| ^^^^^^^^^^^^^
error: delegation to a trait method from a free function is not supported yet
--> $DIR/target-expr.rs:16:18
|
LL | fn static_method(x: i32) -> i32 { x }
| ------------------------------- callee defined here
...
LL | reuse Trait::static_method {
| ^^^^^^^^^^^^^
error: delegation to a trait method from a free function is not supported yet
--> $DIR/target-expr.rs:27:25
|
LL | fn static_method(x: i32) -> i32 { x }
| ------------------------------- callee defined here
...
LL | reuse <S as Trait>::static_method {
| ^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/target-expr.rs:16:32
|
@ -54,12 +72,13 @@ LL | reuse Trait::static_method {
| ________________________________^
LL | |
LL | |
LL | |
LL | | let _ = T::Default();
LL | |
LL | | }
| |_____^ expected `i32`, found `()`
error: aborting due to 6 previous errors
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434.
For more information about an error, try `rustc --explain E0308`.

View File

@ -0,0 +1,20 @@
// Verifies that drops can be called on arbitrary trait objects.
//
// FIXME(#122848): Remove only-linux when fixed.
//@ only-linux
//@ needs-sanitizer-cfi
//@ compile-flags: -Clto -Copt-level=0 -Cprefer-dynamic=off -Ctarget-feature=-crt-static -Zsanitizer=cfi
//@ run-pass
struct EmptyDrop;
struct NonEmptyDrop;
impl Drop for NonEmptyDrop {
fn drop(&mut self) {}
}
fn main() {
let _ = Box::new(EmptyDrop) as Box<dyn Send>;
let _ = Box::new(NonEmptyDrop) as Box<dyn Send>;
}

View File

@ -546,6 +546,15 @@ help: use type parameters instead
LL | fn fn_test10<T>(&self, _x : T) { }
| +++ ~
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
--> $DIR/typeck_type_placeholder_item.rs:194:14
|
LL | const D: _ = 42;
| ^
| |
| not allowed in type signatures
| help: replace with the correct type: `i32`
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/typeck_type_placeholder_item.rs:217:31
|
@ -574,19 +583,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:209:14
|
LL | const D: _ = 42;
| ^
| |
| not allowed in type signatures
| help: replace with the correct type: `i32`
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
--> $DIR/typeck_type_placeholder_item.rs:194:14
|
LL | const D: _ = 42;
| ^
| |
| not allowed in type signatures
| help: replace with the correct type: `i32`
| ^ not allowed in type signatures
error[E0046]: not all trait items implemented, missing: `F`
--> $DIR/typeck_type_placeholder_item.rs:200:1

View File

@ -717,6 +717,9 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
[mentions."src/doc/unstable-book/src/compiler-flags/check-cfg.md"]
cc = ["@Urgau"]
[mentions."src/doc/rustc/src/platform-support"]
cc = ["@Nilstrieb"]
[mentions."tests/codegen/sanitizer"]
cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]