Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #72432

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -312,11 +312,11 @@

# Whether or not debug assertions are enabled for the compiler and standard
# library.
#debug-assertions = false
#debug-assertions = debug

# Whether or not debug assertions are enabled for the standard library.
# Overrides the `debug-assertions` option, if defined.
#debug-assertions-std = false
#debug-assertions-std = debug-assertions

# Debuginfo level for most of Rust code, corresponds to the `-C debuginfo=N` option of `rustc`.
# `0` - no debug info
Expand Down
31 changes: 30 additions & 1 deletion src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5740,7 +5740,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
/// and it must be properly aligned. This means in particular:
///
/// * The entire memory range of this slice must be contained within a single allocated object!
/// Slices can never span across multiple allocated objects.
/// Slices can never span across multiple allocated objects. See [below](#incorrect-usage)
/// for an example incorrectly not taking this into account.
/// * `data` must be non-null and aligned even for zero-length slices. One
/// reason for this is that enum layout optimizations may rely on references
/// (including slices of any length) being aligned and non-null to distinguish
Expand Down Expand Up @@ -5773,6 +5774,34 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
/// assert_eq!(slice[0], 42);
/// ```
///
/// ### Incorrect usage
///
/// The following `join_slices` function is **unsound** ⚠️
///
/// ```rust,no_run
/// use std::slice;
///
/// fn join_slices<'a, T>(fst: &'a [T], snd: &'a [T]) -> &'a [T] {
/// let fst_end = fst.as_ptr().wrapping_add(fst.len());
/// let snd_start = snd.as_ptr();
/// assert_eq!(fst_end, snd_start, "Slices must be contiguous!");
/// unsafe {
/// // The assertion above ensures `fst` and `snd` are contiguous, but they might
/// // still be contained within _different allocated objects_, in which case
/// // creating this slice is undefined behavior.
/// slice::from_raw_parts(fst.as_ptr(), fst.len() + snd.len())
/// }
/// }
///
/// fn main() {
/// // `a` and `b` are different allocated objects...
/// let a = 42;
/// let b = 27;
/// // ... which may nevertheless be laid out contiguously in memory: | a | b |
/// let _ = join_slices(slice::from_ref(&a), slice::from_ref(&b)); // UB
/// }
/// ```
///
/// [valid]: ../../std/ptr/index.html#safety
/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
Expand Down
13 changes: 6 additions & 7 deletions src/librustc_middle/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,19 +815,18 @@ fn foo(&self) -> Self::T { String::new() }
for item in &items[..] {
match item.kind {
hir::AssocItemKind::Type | hir::AssocItemKind::OpaqueTy => {
if self.type_of(self.hir().local_def_id(item.id.hir_id)) == found {
if let hir::Defaultness::Default { has_value: true } =
item.defaultness
{
// FIXME: account for returning some type in a trait fn impl that has
// an assoc type as a return type (#72076).
if let hir::Defaultness::Default { has_value: true } = item.defaultness
{
if self.type_of(self.hir().local_def_id(item.id.hir_id)) == found {
db.span_label(
item.span,
"associated type defaults can't be assumed inside the \
trait defining them",
);
} else {
db.span_label(item.span, "expected this associated type");
return true;
}
return true;
}
}
_ => {}
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_mir/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let place = self.deref_operand(args[0])?;
let discr_val = self.read_discriminant(place.into())?.0;
let scalar = match dest.layout.ty.kind {
ty::Int(_) => Scalar::from_int(discr_val as i128, dest.layout.size),
ty::Int(_) => Scalar::from_int(
self.sign_extend(discr_val, dest.layout) as i128,
dest.layout.size,
),
ty::Uint(_) => Scalar::from_uint(discr_val, dest.layout.size),
_ => bug!("invalid `discriminant_value` return layout: {:?}", dest.layout),
};
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ a {
display: initial;
}

.in-band:hover > .anchor {
.in-band:hover > .anchor, .impl:hover > .anchor {
display: inline-block;
position: absolute;
}
Expand Down
61 changes: 35 additions & 26 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,37 +232,46 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias,
did,
) => {
// We need item's parent to know if it's
// trait impl or struct/enum/etc impl
let item_parent = item_opt
// Checks if item_name belongs to `impl SomeItem`
let impl_item = cx
.tcx
.inherent_impls(did)
.iter()
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
.find(|item| item.ident.name == item_name);
let trait_item = item_opt
.and_then(|item| self.cx.as_local_hir_id(item.def_id))
.and_then(|item_hir| {
// Checks if item_name belongs to `impl SomeTrait for SomeItem`
let parent_hir = self.cx.tcx.hir().get_parent_item(item_hir);
self.cx.tcx.hir().find(parent_hir)
let item_parent = self.cx.tcx.hir().find(parent_hir);
match item_parent {
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl { of_trait: Some(_), self_ty, .. },
..
})) => cx
.tcx
.associated_item_def_ids(self_ty.hir_id.owner)
.iter()
.map(|child| {
let associated_item = cx.tcx.associated_item(*child);
associated_item
})
.find(|child| child.ident.name == item_name),
_ => None,
}
});
let item = match item_parent {
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl { of_trait: Some(_), self_ty, .. },
..
})) => {
// trait impl
cx.tcx
.associated_item_def_ids(self_ty.hir_id.owner)
.iter()
.map(|child| {
let associated_item = cx.tcx.associated_item(*child);
associated_item
})
.find(|child| child.ident.name == item_name)
}
_ => {
// struct/enum/etc. impl
cx.tcx
.inherent_impls(did)
.iter()
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
.find(|item| item.ident.name == item_name)
let item = match (impl_item, trait_item) {
(Some(from_impl), Some(_)) => {
// Although it's ambiguous, return impl version for compat. sake.
// To handle that properly resolve() would have to support
// something like
// [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
Some(from_impl)
}
(None, Some(from_trait)) => Some(from_trait),
(Some(from_impl), None) => Some(from_impl),
_ => None,
};

if let Some(item) = item {
Expand Down
19 changes: 19 additions & 0 deletions src/test/rustdoc/issue-72340.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![crate_name = "foo"]

pub struct Body;

impl Body {
pub fn empty() -> Self {
Body
}

}

impl Default for Body {
// @has foo/struct.Body.html '//a/@href' '../foo/struct.Body.html#method.empty'

/// Returns [`Body::empty()`](Body::empty).
fn default() -> Body {
Body::empty()
}
}
6 changes: 6 additions & 0 deletions src/test/ui/issues/issue-72076.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
trait X {
type S;
fn f() -> Self::S {} //~ ERROR mismatched types
}

fn main() {}
14 changes: 14 additions & 0 deletions src/test/ui/issues/issue-72076.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/issue-72076.rs:3:23
|
LL | fn f() -> Self::S {}
| ^^ expected associated type, found `()`
|
= note: expected associated type `<Self as X>::S`
found unit type `()`
= help: consider constraining the associated type `<Self as X>::S` to `()` or calling a method that returns `<Self as X>::S`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ trait Trait<T = Self> {

fn func(&self) -> Self::A;
fn funk(&self, _: Self::A);
fn funq(&self) -> Self::A {} //~ ERROR mismatched types
}

fn foo(_: impl Trait, x: impl Trait) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:13:9
--> $DIR/trait-with-missing-associated-type-restriction.rs:10:31
|
LL | fn funq(&self) -> Self::A {}
| ^^ expected associated type, found `()`
|
= note: expected associated type `<Self as Trait<T>>::A`
found unit type `()`
help: a method is available that returns `<Self as Trait<T>>::A`
--> $DIR/trait-with-missing-associated-type-restriction.rs:8:5
|
LL | fn func(&self) -> Self::A;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::func`

error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:14:9
|
LL | qux(x.func())
| ^^^^^^^^ expected `usize`, found associated type
Expand All @@ -12,7 +26,7 @@ LL | fn foo(_: impl Trait, x: impl Trait<A = usize>) {
| ^^^^^^^^^^^

error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:17:9
--> $DIR/trait-with-missing-associated-type-restriction.rs:18:9
|
LL | qux(x.func())
| ^^^^^^^^ expected `usize`, found associated type
Expand All @@ -25,7 +39,7 @@ LL | fn bar<T: Trait<A = usize>>(x: T) {
| ^^^^^^^^^^^

error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:21:9
--> $DIR/trait-with-missing-associated-type-restriction.rs:22:9
|
LL | qux(x.func())
| ^^^^^^^^ expected `usize`, found associated type
Expand All @@ -38,25 +52,28 @@ LL | fn foo2(x: impl Trait<i32, A = usize>) {
| ^^^^^^^^^^^

error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:25:12
--> $DIR/trait-with-missing-associated-type-restriction.rs:26:12
|
LL | x.funk(3);
| ^ expected associated type, found integer
|
= note: expected associated type `<T as Trait<i32>>::A`
found type `{integer}`
help: a method is available that returns `<T as Trait<i32>>::A`
help: some methods are available that return `<T as Trait<i32>>::A`
--> $DIR/trait-with-missing-associated-type-restriction.rs:8:5
|
LL | fn func(&self) -> Self::A;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::func`
LL | fn funk(&self, _: Self::A);
LL | fn funq(&self) -> Self::A {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::funq`
help: consider constraining the associated type `<T as Trait<i32>>::A` to `{integer}`
|
LL | fn bar2<T: Trait<i32, A = {integer}>>(x: T) {
| ^^^^^^^^^^^^^^^

error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:26:9
--> $DIR/trait-with-missing-associated-type-restriction.rs:27:9
|
LL | qux(x.func())
| ^^^^^^^^ expected `usize`, found associated type
Expand All @@ -69,7 +86,7 @@ LL | fn bar2<T: Trait<i32, A = usize>>(x: T) {
| ^^^^^^^^^^^

error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:30:9
--> $DIR/trait-with-missing-associated-type-restriction.rs:31:9
|
LL | fn baz<D: std::fmt::Debug, T: Trait<A = D>>(x: T) {
| - this type parameter
Expand All @@ -80,13 +97,13 @@ LL | qux(x.func())
found type parameter `D`

error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:34:9
--> $DIR/trait-with-missing-associated-type-restriction.rs:35:9
|
LL | qux(x.func())
| ^^^^^^^^ expected `usize`, found `()`

error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:38:9
--> $DIR/trait-with-missing-associated-type-restriction.rs:39:9
|
LL | qux(x.func())
| ^^^^^^^^ expected `usize`, found associated type
Expand All @@ -98,6 +115,6 @@ help: consider constraining the associated type `<T as Trait>::A` to `usize`
LL | fn ban<T>(x: T) where T: Trait<A = usize> {
| ^^^^^^^^^^^

error: aborting due to 8 previous errors
error: aborting due to 9 previous errors

For more information about this error, try `rustc --explain E0308`.