Skip to content

Rollup of 6 pull requests #103921

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

Closed
wants to merge 12 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
2 changes: 1 addition & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Language
- [Error on `as` casts of enums with `#[non_exhaustive]` variants](https://github.com/rust-lang/rust/pull/92744/)
- [Stabilize `let else`](https://github.com/rust-lang/rust/pull/93628/)
- [Stabilize generic associated types (GATs)](https://github.com/rust-lang/rust/pull/96709/)
- [Add lints `let_underscore_drop`, `let_underscore_lock`, and `let_underscore_must_use` from Clippy](https://github.com/rust-lang/rust/pull/97739/)
- [Add lints `let_underscore_drop` and `let_underscore_lock` from Clippy](https://github.com/rust-lang/rust/pull/97739/)
- [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")](https://github.com/rust-lang/rust/pull/99332/)
- [Uninitialized integers, floats, and raw pointers are now considered immediate UB](https://github.com/rust-lang/rust/pull/98919/).
Usage of `MaybeUninit` is the correct way to work with uninitialized memory.
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_data_structures/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ impl<T> Lock<T> {

#[cfg(parallel_compiler)]
#[inline(always)]
#[track_caller]
pub fn lock(&self) -> LockGuard<'_, T> {
if ERROR_CHECKING {
self.0.try_lock().expect("lock was already held")
Expand All @@ -420,21 +421,25 @@ impl<T> Lock<T> {

#[cfg(not(parallel_compiler))]
#[inline(always)]
#[track_caller]
pub fn lock(&self) -> LockGuard<'_, T> {
self.0.borrow_mut()
}

#[inline(always)]
#[track_caller]
pub fn with_lock<F: FnOnce(&mut T) -> R, R>(&self, f: F) -> R {
f(&mut *self.lock())
}

#[inline(always)]
#[track_caller]
pub fn borrow(&self) -> LockGuard<'_, T> {
self.lock()
}

#[inline(always)]
#[track_caller]
pub fn borrow_mut(&self) -> LockGuard<'_, T> {
self.lock()
}
Expand Down Expand Up @@ -476,6 +481,7 @@ impl<T> RwLock<T> {

#[cfg(not(parallel_compiler))]
#[inline(always)]
#[track_caller]
pub fn read(&self) -> ReadGuard<'_, T> {
self.0.borrow()
}
Expand All @@ -491,6 +497,7 @@ impl<T> RwLock<T> {
}

#[inline(always)]
#[track_caller]
pub fn with_read_lock<F: FnOnce(&T) -> R, R>(&self, f: F) -> R {
f(&*self.read())
}
Expand All @@ -509,6 +516,7 @@ impl<T> RwLock<T> {

#[cfg(not(parallel_compiler))]
#[inline(always)]
#[track_caller]
pub fn write(&self) -> WriteGuard<'_, T> {
self.0.borrow_mut()
}
Expand All @@ -524,16 +532,19 @@ impl<T> RwLock<T> {
}

#[inline(always)]
#[track_caller]
pub fn with_write_lock<F: FnOnce(&mut T) -> R, R>(&self, f: F) -> R {
f(&mut *self.write())
}

#[inline(always)]
#[track_caller]
pub fn borrow(&self) -> ReadGuard<'_, T> {
self.read()
}

#[inline(always)]
#[track_caller]
pub fn borrow_mut(&self) -> WriteGuard<'_, T> {
self.write()
}
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Hide the outer diverging and has_errors flags.
let old_diverges = self.diverges.replace(Diverges::Maybe);
let old_has_errors = self.has_errors.replace(false);

let ty = ensure_sufficient_stack(|| match &expr.kind {
hir::ExprKind::Path(
Expand Down Expand Up @@ -259,7 +258,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Combine the diverging and has_error flags.
self.diverges.set(self.diverges.get() | old_diverges);
self.has_errors.set(self.has_errors.get() | old_has_errors);

debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id));
debug!("... {:?}, expected is {:?}", ty, expected);
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);

if ty.references_error() {
self.has_errors.set(true);
self.set_tainted_by_errors();
}
}
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Hide the outer diverging and `has_errors` flags.
let old_diverges = self.diverges.replace(Diverges::Maybe);
let old_has_errors = self.has_errors.replace(false);

match stmt.kind {
hir::StmtKind::Local(l) => {
Expand Down Expand Up @@ -1364,7 +1363,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Combine the diverging and `has_error` flags.
self.diverges.set(self.diverges.get() | old_diverges);
self.has_errors.set(self.has_errors.get() | old_has_errors);
}

pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
Expand Down Expand Up @@ -1544,11 +1542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.diverges.set(prev_diverges);
}

let mut ty = ctxt.coerce.unwrap().complete(self);

if self.has_errors.get() || ty.references_error() {
ty = self.tcx.ty_error()
}
let ty = ctxt.coerce.unwrap().complete(self);

self.write_ty(blk.hir_id, ty);

Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,6 @@ pub struct FnCtxt<'a, 'tcx> {
/// the diverges flag is set to something other than `Maybe`.
pub(super) diverges: Cell<Diverges>,

/// Whether any child nodes have any type errors.
pub(super) has_errors: Cell<bool>,

pub(super) enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,

pub(super) inh: &'a Inherited<'tcx>,
Expand Down Expand Up @@ -145,7 +142,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
resume_yield_tys: None,
ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
diverges: Cell::new(Diverges::Maybe),
has_errors: Cell::new(false),
enclosing_breakables: RefCell::new(EnclosingBreakables {
stack: Vec::new(),
by_id: Default::default(),
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1865,6 +1865,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Str
| ty::Projection(_)
| ty::Param(_) => format!("{deref_ty}"),
// we need to test something like <&[_]>::len
// and Vec::function();
// <&[_]>::len doesn't need an extra "<>" between
// but for Adt type like Vec::function()
// we would suggest <[_]>::function();
_ if self.tcx.sess.source_map().span_wrapped_by_angle_bracket(ty.span) => format!("{deref_ty}"),
_ => format!("<{deref_ty}>"),
};
err.span_suggestion_verbose(
Expand Down
44 changes: 44 additions & 0 deletions compiler/rustc_span/src/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,50 @@ impl SourceMap {
}
}

/// Given a 'Span', tries to tell if the next character is '>'
/// and the previous charactoer is '<' after skipping white space
/// return true if wrapped by '<>'
pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool {
self.span_to_source(span, |src, start_index, end_index| {
if src.get(start_index..end_index).is_none() {
return Ok(false);
}
// test the right side to match '>' after skipping white space
let end_src = &src[end_index..];
let mut i = 0;
while let Some(cc) = end_src.chars().nth(i) {
if cc == ' ' {
i = i + 1;
} else if cc == '>' {
// found > in the right;
break;
} else {
// failed to find '>' return false immediately
return Ok(false);
}
}
// test the left side to match '<' after skipping white space
i = start_index;
let start_src = &src[0..start_index];
while let Some(cc) = start_src.chars().nth(i) {
if cc == ' ' {
if i == 0 {
return Ok(false);
}
i = i - 1;
} else if cc == '<' {
// found < in the left
break;
} else {
// failed to find '<' return false immediately
return Ok(false);
}
}
return Ok(true);
})
.map_or(false, |is_accessible| is_accessible)
}

/// Given a `Span`, tries to get a shorter span ending just after the first occurrence of `char`
/// `c`.
pub fn span_through_char(&self, sp: Span, c: char) -> Span {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Ty<'_>> {
/// Check if a function is async.
fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
let node = tcx.hir().get_by_def_id(def_id.expect_local());
if let Some(fn_kind) = node.fn_kind() { fn_kind.asyncness() } else { hir::IsAsync::NotAsync }
node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness)
}

/// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead.
Expand Down
32 changes: 19 additions & 13 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ fn clean_fn_or_proc_macro<'tcx>(
ProcMacroItem(ProcMacro { kind, helpers })
}
None => {
let mut func = clean_function(cx, sig, generics, body_id);
let mut func = clean_function(cx, sig, generics, FunctionArgs::Body(body_id));
clean_fn_decl_legacy_const_generics(&mut func, attrs);
FunctionItem(func)
}
Expand Down Expand Up @@ -917,16 +917,28 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
}
}

enum FunctionArgs<'tcx> {
Body(hir::BodyId),
Names(&'tcx [Ident]),
}

fn clean_function<'tcx>(
cx: &mut DocContext<'tcx>,
sig: &hir::FnSig<'tcx>,
generics: &hir::Generics<'tcx>,
body_id: hir::BodyId,
args: FunctionArgs<'tcx>,
) -> Box<Function> {
let (generics, decl) = enter_impl_trait(cx, |cx| {
// NOTE: generics must be cleaned before args
let generics = clean_generics(generics, cx);
let args = clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id);
let args = match args {
FunctionArgs::Body(body_id) => {
clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id)
}
FunctionArgs::Names(names) => {
clean_args_from_types_and_names(cx, sig.decl.inputs, names)
}
};
let mut decl = clean_fn_decl_with_args(cx, sig.decl, args);
if sig.header.is_async() {
decl.output = decl.sugared_async_return_type();
Expand Down Expand Up @@ -1051,18 +1063,12 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
),
hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(clean_ty(ty, cx)),
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
let m = clean_function(cx, sig, trait_item.generics, body);
let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body));
MethodItem(m, None)
}
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => {
let (generics, decl) = enter_impl_trait(cx, |cx| {
// NOTE: generics must be cleaned before args
let generics = clean_generics(trait_item.generics, cx);
let args = clean_args_from_types_and_names(cx, sig.decl.inputs, names);
let decl = clean_fn_decl_with_args(cx, sig.decl, args);
(generics, decl)
});
TyMethodItem(Box::new(Function { decl, generics }))
let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names));
TyMethodItem(m)
}
hir::TraitItemKind::Type(bounds, Some(default)) => {
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
Expand Down Expand Up @@ -1099,7 +1105,7 @@ pub(crate) fn clean_impl_item<'tcx>(
AssocConstItem(clean_ty(ty, cx), default)
}
hir::ImplItemKind::Fn(ref sig, body) => {
let m = clean_function(cx, sig, impl_.generics, body);
let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body));
let defaultness = cx.tcx.impl_defaultness(impl_.owner_id);
MethodItem(m, Some(defaultness))
}
Expand Down
5 changes: 1 addition & 4 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -694,13 +694,10 @@ impl Item {
asyncness: hir::IsAsync::NotAsync,
}
}
ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) => {
ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) | ItemKind::TyMethodItem(_) => {
let def_id = self.item_id.as_def_id().unwrap();
build_fn_header(def_id, tcx, tcx.asyncness(def_id))
}
ItemKind::TyMethodItem(_) => {
build_fn_header(self.item_id.as_def_id().unwrap(), tcx, hir::IsAsync::NotAsync)
}
_ => return None,
};
Some(header)
Expand Down
1 change: 0 additions & 1 deletion src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -1796,7 +1796,6 @@ in storage.js

.sidebar-elems {
margin-top: 1em;
background-color: var(--sidebar-background-color);
}

.content {
Expand Down
14 changes: 14 additions & 0 deletions src/test/rustdoc/async-trait-sig.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// edition:2021

#![feature(async_fn_in_trait)]
#![allow(incomplete_features)]

pub trait Foo {
// @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn bar() -> i32"
async fn bar() -> i32;

// @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn baz() -> i32"
async fn baz() -> i32 {
1
}
}
3 changes: 2 additions & 1 deletion src/test/ui/error-codes/E0767.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
fn main () {
fn main() {
'a: loop {
|| {
//~^ ERROR mismatched types
loop { break 'a; } //~ ERROR E0767
}
}
Expand Down
21 changes: 17 additions & 4 deletions src/test/ui/error-codes/E0767.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
error[E0767]: use of unreachable label `'a`
--> $DIR/E0767.rs:4:26
--> $DIR/E0767.rs:5:26
|
LL | 'a: loop {
| -- unreachable label defined here
LL | || {
...
LL | loop { break 'a; }
| ^^ unreachable label `'a`
|
= note: labels are unreachable through functions, closures, async blocks and modules

error: aborting due to previous error
error[E0308]: mismatched types
--> $DIR/E0767.rs:3:9
|
LL | / || {
LL | |
LL | | loop { break 'a; }
LL | | }
| |_________^ expected `()`, found closure
|
= note: expected unit type `()`
found closure `[closure@$DIR/E0767.rs:3:9: 3:11]`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0767`.
Some errors have detailed explanations: E0308, E0767.
For more information about an error, try `rustc --explain E0308`.
9 changes: 9 additions & 0 deletions src/test/ui/type/issue-103271.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fn main() {
//~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it:
let length = <&[_]>::len;
//~^ ERROR the function or associated item `len` exists for reference `&[_]`, but its trait bounds were not satisfied [E0599]
//~| function or associated item cannot be called on `&[_]` due to unsatisfied trait bounds
//~| HELP items from traits can only be used if the trait is in scope
//~| HELP the function `len` is implemented on `[_]`
assert_eq!(length(&[1,3]), 2);
}
Loading