summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock6
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs2
-rw-r--r--compiler/rustc_data_structures/src/sso/set.rs5
-rw-r--r--compiler/rustc_errors/src/emitter.rs37
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs9
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs2
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs42
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs16
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs16
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs2
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs15
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs15
-rw-r--r--compiler/rustc_resolve/src/imports.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs13
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs203
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs2
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs47
-rw-r--r--library/alloc/src/collections/btree/set.rs10
-rw-r--r--library/alloc/src/vec/mod.rs2
-rw-r--r--library/core/src/num/dec2flt/mod.rs1
-rw-r--r--library/core/src/ptr/mut_ptr.rs119
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/collections/hash/map.rs113
-rw-r--r--library/std/src/collections/hash/set.rs5
-rw-r--r--src/librustdoc/clean/types.rs4
-rw-r--r--src/librustdoc/formats/mod.rs25
-rw-r--r--src/librustdoc/html/render/mod.rs4
-rw-r--r--src/librustdoc/html/render/print_item.rs5
-rw-r--r--src/librustdoc/html/render/search_index.rs35
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs31
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff4
-rw-r--r--src/test/rustdoc-js/impl-trait.js51
-rw-r--r--src/test/rustdoc-js/impl-trait.rs21
-rw-r--r--src/test/rustdoc-js/raw-pointer.js55
-rw-r--r--src/test/rustdoc-js/raw-pointer.rs24
-rw-r--r--src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr2
-rw-r--r--src/test/rustdoc-ui/issue-61732.stderr2
-rw-r--r--src/test/rustdoc/inline_cross/auxiliary/implementors_inline.rs18
-rw-r--r--src/test/rustdoc/inline_cross/implementors-js.rs25
-rw-r--r--src/test/rustdoc/intra-doc/email-address.rs6
-rw-r--r--src/test/rustdoc/issue-75588.rs2
-rw-r--r--src/test/rustdoc/primitive-slice-auto-trait.rs14
-rw-r--r--src/test/ui/attributes/field-attributes-vis-unresolved.stderr4
-rw-r--r--src/test/ui/borrowck/issue-71546.rs19
-rw-r--r--src/test/ui/borrowck/issue-71546.stderr20
-rw-r--r--src/test/ui/codemap_tests/two_files.stderr1
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-94287.stderr1
-rw-r--r--src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr1
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr1
-rw-r--r--src/test/ui/error-codes/E0432.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr4
-rw-r--r--src/test/ui/imports/import3.stderr2
-rw-r--r--src/test/ui/imports/issue-1697.stderr2
-rw-r--r--src/test/ui/imports/issue-33464.stderr6
-rw-r--r--src/test/ui/imports/issue-36881.stderr2
-rw-r--r--src/test/ui/imports/issue-37887.stderr2
-rw-r--r--src/test/ui/imports/issue-53269.stderr2
-rw-r--r--src/test/ui/imports/issue-55457.stderr2
-rw-r--r--src/test/ui/imports/tool-mod-child.stderr8
-rw-r--r--src/test/ui/imports/unresolved-imports-used.stderr8
-rw-r--r--src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr1
-rw-r--r--src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr2
-rw-r--r--src/test/ui/methods/method-on-ambiguous-numeric-type.stderr1
-rw-r--r--src/test/ui/privacy/restricted/test.stderr2
-rw-r--r--src/test/ui/resolve/editions-crate-root-2015.stderr4
-rw-r--r--src/test/ui/resolve/extern-prelude-fail.stderr4
-rw-r--r--src/test/ui/resolve/issue-82865.stderr2
-rw-r--r--src/test/ui/resolve/resolve-bad-visibility.stderr4
-rw-r--r--src/test/ui/simd/portable-intrinsics-arent-exposed.stderr2
-rw-r--r--src/test/ui/suggestions/enum-method-probe.fixed59
-rw-r--r--src/test/ui/suggestions/enum-method-probe.rs59
-rw-r--r--src/test/ui/suggestions/enum-method-probe.stderr99
-rw-r--r--src/test/ui/unresolved/unresolved-asterisk-imports.stderr2
-rw-r--r--src/test/ui/unresolved/unresolved-import.rs1
-rw-r--r--src/test/ui/unresolved/unresolved-import.stderr12
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
m---------src/tools/miri19
87 files changed, 1210 insertions, 222 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c066d1b0a5b..7ed327e9f4c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -746,9 +746,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
-version = "0.1.71"
+version = "0.1.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "163437f05ca8f29d7e9128ea728dedf5eb620e445fbca273641d3a3050305f23"
+checksum = "71b72fde1d7792ca3bd654f7c3ea4508f9e4d0c826e24179eabb7fcc97a90bc3"
dependencies = [
"cc",
"rustc-std-workspace-core",
@@ -5509,6 +5509,8 @@ dependencies = [
"pretty_assertions 1.2.1",
"regex",
"rustc_version",
+ "serde",
+ "serde_json",
]
[[package]]
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index d9d31ab2c89..abf77acb8c7 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2147,7 +2147,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
}
- CastKind::PointerAddress => {
+ CastKind::PointerExposeAddress => {
let ty_from = op.ty(body, tcx);
let cast_ty_from = CastTy::from_ty(ty_from);
let cast_ty_to = CastTy::from_ty(*ty);
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 7c59ce354c0..58bec183c94 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -607,7 +607,11 @@ fn codegen_stmt<'tcx>(
let operand = codegen_operand(fx, operand);
lval.write_cvalue(fx, operand.cast_pointer_to(to_layout));
}
- Rvalue::Cast(CastKind::Misc | CastKind::PointerAddress, ref operand, to_ty) => {
+ Rvalue::Cast(
+ CastKind::Misc | CastKind::PointerExposeAddress,
+ ref operand,
+ to_ty,
+ ) => {
let operand = codegen_operand(fx, operand);
let from_ty = operand.layout().ty;
let to_ty = fx.monomorphize(to_ty);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index bd88aa33372..6ff8d4aa442 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -181,7 +181,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let cast = bx.cx().layout_of(self.monomorphize(mir_cast_ty));
let val = match *kind {
- mir::CastKind::PointerAddress => {
+ mir::CastKind::PointerExposeAddress => {
assert!(bx.cx().is_backend_immediate(cast));
let llptr = operand.immediate();
let llcast_ty = bx.cx().immediate_backend_type(cast);
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index af563c1450e..520ae409e6b 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -31,9 +31,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.unsize_into(src, cast_ty, dest)?;
}
- PointerAddress => {
+ PointerExposeAddress => {
let src = self.read_immediate(src)?;
- let res = self.pointer_address_cast(&src, cast_ty)?;
+ let res = self.pointer_expose_address_cast(&src, cast_ty)?;
self.write_immediate(res, dest)?;
}
@@ -184,7 +184,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
}
- pub fn pointer_address_cast(
+ pub fn pointer_expose_address_cast(
&mut self,
src: &ImmTy<'tcx, M::PointerTag>,
cast_ty: Ty<'tcx>,
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 977b55a0890..9c032c55fe5 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -441,6 +441,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
msg,
})
}
+ // Ensure we never consider the null pointer dereferencable.
+ if M::PointerTag::OFFSET_IS_ADDR {
+ assert_ne!(ptr.addr(), Size::ZERO);
+ }
// Test align. Check this last; if both bounds and alignment are violated
// we want the error to be about the bounds.
if let Some(align) = align {
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 4ef33d62a6b..c07680515f4 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -542,7 +542,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// in the type of any local, which also excludes casts).
}
- Rvalue::Cast(CastKind::PointerAddress, _, _) => {
+ Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
self.check_op(ops::RawPtrToIntCast);
}
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index ea23bd14d25..cf5d7b6c70a 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -502,7 +502,7 @@ impl<'tcx> Validator<'_, 'tcx> {
Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),
// ptr-to-int casts are not possible in consts and thus not promotable
- Rvalue::Cast(CastKind::PointerAddress, _, _) => return Err(Unpromotable),
+ Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => return Err(Unpromotable),
// int-to-ptr casts are fine, they just use the integer value at pointer type.
Rvalue::Cast(_, operand, _) => {
diff --git a/compiler/rustc_data_structures/src/sso/set.rs b/compiler/rustc_data_structures/src/sso/set.rs
index f71522d3714..4fda3adb7b8 100644
--- a/compiler/rustc_data_structures/src/sso/set.rs
+++ b/compiler/rustc_data_structures/src/sso/set.rs
@@ -126,9 +126,10 @@ impl<T: Eq + Hash> SsoHashSet<T> {
/// Adds a value to the set.
///
- /// If the set did not have this value present, `true` is returned.
+ /// Returns whether the value was newly inserted. That is:
///
- /// If the set did have this value present, `false` is returned.
+ /// - If the set did not previously contain this value, `true` is returned.
+ /// - If the set already contained this value, `false` is returned.
#[inline]
pub fn insert(&mut self, elem: T) -> bool {
self.map.insert(elem, ()).is_none()
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 3fdc8cf8ac2..e9e7065ec03 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -1715,6 +1715,7 @@ impl EmitterWriter {
fn emit_suggestion_default(
&mut self,
+ span: &MultiSpan,
suggestion: &CodeSuggestion,
args: &FluentArgs<'_>,
level: &Level,
@@ -1766,6 +1767,30 @@ impl EmitterWriter {
None,
}
+ if let Some(span) = span.primary_span() {
+ // Compare the primary span of the diagnostic with the span of the suggestion
+ // being emitted. If they belong to the same file, we don't *need* to show the
+ // file name, saving in verbosity, but if it *isn't* we do need it, otherwise we're
+ // telling users to make a change but not clarifying *where*.
+ let loc = sm.lookup_char_pos(parts[0].span.lo());
+ if loc.file.name != sm.span_to_filename(span) && loc.file.name.is_real() {
+ buffer.puts(row_num - 1, 0, "--> ", Style::LineNumber);
+ buffer.append(
+ row_num - 1,
+ &format!(
+ "{}:{}:{}",
+ sm.filename_for_diagnostics(&loc.file.name),
+ sm.doctest_offset_line(&loc.file.name, loc.line),
+ loc.col.0 + 1,
+ ),
+ Style::LineAndColumn,
+ );
+ for _ in 0..max_line_num_len {
+ buffer.prepend(row_num - 1, " ", Style::NoStyle);
+ }
+ row_num += 1;
+ }
+ }
let show_code_change = if has_deletion && !is_multiline {
DisplaySuggestion::Diff
} else if (parts.len() != 1 || parts[0].snippet.trim() != complete.trim())
@@ -1787,7 +1812,7 @@ impl EmitterWriter {
assert!(!file_lines.lines.is_empty() || parts[0].span.is_dummy());
let line_start = sm.lookup_char_pos(parts[0].span.lo()).line;
- draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1);
+ draw_col_separator_no_space(&mut buffer, row_num - 1, max_line_num_len + 1);
let mut lines = complete.lines();
if lines.clone().next().is_none() {
// Account for a suggestion to completely remove a line(s) with whitespace (#94192).
@@ -2046,9 +2071,13 @@ impl EmitterWriter {
) {
panic!("failed to emit error: {}", e);
}
- } else if let Err(e) =
- self.emit_suggestion_default(sugg, args, &Level::Help, max_line_num_len)
- {
+ } else if let Err(e) = self.emit_suggestion_default(
+ span,
+ sugg,
+ args,
+ &Level::Help,
+ max_line_num_len,
+ ) {
panic!("failed to emit error: {}", e);
};
}
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 1b63c8d67ca..d9cdca8bcb5 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2607,16 +2607,17 @@ static_assert_size!(Rvalue<'_>, 40);
impl<'tcx> Rvalue<'tcx> {
#[inline]
pub fn is_pointer_int_cast(&self) -> bool {
- matches!(self, Rvalue::Cast(CastKind::PointerAddress, _, _))
+ matches!(self, Rvalue::Cast(CastKind::PointerExposeAddress, _, _))
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
pub enum CastKind {
Misc,
- /// A pointer to address cast. A cast between a pointer and an integer type,
- /// or between a function pointer and an integer type.
- PointerAddress,
+ /// An exposing pointer to address cast. A cast between a pointer and an integer type, or
+ /// between a function pointer and an integer type.
+ /// See the docs on `expose_addr` for more details.
+ PointerExposeAddress,
Pointer(PointerCast),
}
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 2b137046c7f..7d08b20631e 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -194,7 +194,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let cast_ty = CastTy::from_ty(expr.ty);
let cast_kind = match (from_ty, cast_ty) {
(Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
- CastKind::PointerAddress
+ CastKind::PointerExposeAddress
}
(_, _) => CastKind::Misc,
};
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 12302315e90..ee8e4162001 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1,8 +1,7 @@
use super::pat::Expected;
-use super::ty::{AllowPlus, RecoverQuestionMark};
use super::{
- BlockMode, CommaRecoveryMode, Parser, PathStyle, RecoverColon, RecoverComma, Restrictions,
- SemiColonMode, SeqSep, TokenExpectType, TokenType,
+ BlockMode, CommaRecoveryMode, Parser, PathStyle, Restrictions, SemiColonMode, SeqSep,
+ TokenExpectType, TokenType,
};
use crate::lexer::UnmatchedBrace;
@@ -1233,26 +1232,14 @@ impl<'a> Parser<'a> {
}
}
- pub(super) fn maybe_report_ambiguous_plus(
- &mut self,
- allow_plus: AllowPlus,
- impl_dyn_multi: bool,
- ty: &Ty,
- ) {
- if matches!(allow_plus, AllowPlus::No) && impl_dyn_multi {
+ pub(super) fn maybe_report_ambiguous_plus(&mut self, impl_dyn_multi: bool, ty: &Ty) {
+ if impl_dyn_multi {
self.sess.emit_err(AmbiguousPlus { sum_ty: pprust::ty_to_string(&ty), span: ty.span });
}
}
/// Swift lets users write `Ty?` to mean `Option<Ty>`. Parse the construct and recover from it.
- pub(super) fn maybe_recover_from_question_mark(
- &mut self,
- ty: P<Ty>,
- recover_question_mark: RecoverQuestionMark,
- ) -> P<Ty> {
- if let RecoverQuestionMark::No = recover_question_mark {
- return ty;
- }
+ pub(super) fn maybe_recover_from_question_mark(&mut self, ty: P<Ty>) -> P<Ty> {
if self.token == token::Question {
self.bump();
self.struct_span_err(self.prev_token.span, "invalid `?` in type")
@@ -1272,13 +1259,9 @@ impl<'a> Parser<'a> {
}
}
- pub(super) fn maybe_recover_from_bad_type_plus(
- &mut self,
- allow_plus: AllowPlus,
- ty: &Ty,
- ) -> PResult<'a, ()> {
+ pub(super) fn maybe_recover_from_bad_type_plus(&mut self, ty: &Ty) -> PResult<'a, ()> {
// Do not add `+` to expected tokens.
- if matches!(allow_plus, AllowPlus::No) || !self.token.is_like_plus() {
+ if !self.token.is_like_plus() {
return Ok(());
}
@@ -1444,10 +1427,9 @@ impl<'a> Parser<'a> {
pub(super) fn maybe_recover_from_bad_qpath<T: RecoverQPath>(
&mut self,
base: P<T>,
- allow_recovery: bool,
) -> PResult<'a, P<T>> {
// Do not add `::` to expected tokens.
- if allow_recovery && self.token == token::ModSep {
+ if self.token == token::ModSep {
if let Some(ty) = base.to_ty() {
return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty);
}
@@ -1593,7 +1575,7 @@ impl<'a> Parser<'a> {
_ => ExprKind::Await(expr),
};
let expr = self.mk_expr(lo.to(sp), kind, attrs);
- self.maybe_recover_from_bad_qpath(expr, true)
+ self.maybe_recover_from_bad_qpath(expr)
}
fn recover_await_macro(&mut self) -> PResult<'a, (Span, P<Expr>, bool)> {
@@ -2457,10 +2439,9 @@ impl<'a> Parser<'a> {
pub(crate) fn maybe_recover_colon_colon_in_pat_typo(
&mut self,
mut first_pat: P<Pat>,
- ra: RecoverColon,
expected: Expected,
) -> P<Pat> {
- if RecoverColon::Yes != ra || token::Colon != self.token.kind {
+ if token::Colon != self.token.kind {
return first_pat;
}
if !matches!(first_pat.kind, PatKind::Ident(_, _, None) | PatKind::Path(..))
@@ -2594,10 +2575,9 @@ impl<'a> Parser<'a> {
pub(crate) fn maybe_recover_unexpected_comma(
&mut self,
lo: Span,
- rc: RecoverComma,
rt: CommaRecoveryMode,
) -> PResult<'a, ()> {
- if rc == RecoverComma::No || self.token != token::Comma {
+ if self.token != token::Comma {
return Ok(());
}
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index bb6d892138a..63c7decbb2f 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1417,7 +1417,7 @@ impl<'a> Parser<'a> {
match self.parse_opt_lit() {
Some(literal) => {
let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal), attrs);
- self.maybe_recover_from_bad_qpath(expr, true)
+ self.maybe_recover_from_bad_qpath(expr)
}
None => self.try_macro_suggestion(),
}
@@ -1444,7 +1444,7 @@ impl<'a> Parser<'a> {
ExprKind::Tup(es)
};
let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
- self.maybe_recover_from_bad_qpath(expr, true)
+ self.maybe_recover_from_bad_qpath(expr)
}
fn parse_array_or_repeat_expr(
@@ -1481,7 +1481,7 @@ impl<'a> Parser<'a> {
}
};
let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
- self.maybe_recover_from_bad_qpath(expr, true)
+ self.maybe_recover_from_bad_qpath(expr)
}
fn parse_path_start_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
@@ -1519,7 +1519,7 @@ impl<'a> Parser<'a> {
};
let expr = self.mk_expr(lo.to(hi), kind, attrs);
- self.maybe_recover_from_bad_qpath(expr, true)
+ self.maybe_recover_from_bad_qpath(expr)
}
/// Parse `'label: $expr`. The label is already parsed.
@@ -1604,7 +1604,7 @@ impl<'a> Parser<'a> {
let lo = self.prev_token.span;
let kind = ExprKind::Ret(self.parse_expr_opt()?);
let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
- self.maybe_recover_from_bad_qpath(expr, true)
+ self.maybe_recover_from_bad_qpath(expr)
}
/// Parse `"do" "yeet" expr?`.
@@ -1619,7 +1619,7 @@ impl<'a> Parser<'a> {
let span = lo.to(self.prev_token.span);
self.sess.gated_spans.gate(sym::yeet_expr, span);
let expr = self.mk_expr(span, kind, attrs);
- self.maybe_recover_from_bad_qpath(expr, true)
+ self.maybe_recover_from_bad_qpath(expr)
}
/// Parse `"break" (('label (:? expr)?) | expr?)` with `"break"` token already eaten.
@@ -1679,7 +1679,7 @@ impl<'a> Parser<'a> {
None
};
let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Break(label, kind), attrs);
- self.maybe_recover_from_bad_qpath(expr, true)
+ self.maybe_recover_from_bad_qpath(expr)
}
/// Parse `"yield" expr?`.
@@ -1689,7 +1689,7 @@ impl<'a> Parser<'a> {
let span = lo.to(self.prev_token.span);
self.sess.gated_spans.gate(sym::generators, span);
let expr = self.mk_expr(span, kind, attrs);
- self.maybe_recover_from_bad_qpath(expr, true)
+ self.maybe_recover_from_bad_qpath(expr)
}
/// Returns a string literal if the next token is a string literal.
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 8019c5fb67c..2ad3f3ec19d 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -100,8 +100,10 @@ impl<'a> Parser<'a> {
};
// Parse the first pattern (`p_0`).
- let first_pat = self.parse_pat_no_top_alt(expected)?;
- self.maybe_recover_unexpected_comma(first_pat.span, rc, rt)?;
+ let mut first_pat = self.parse_pat_no_top_alt(expected)?;
+ if rc == RecoverComma::Yes {
+ self.maybe_recover_unexpected_comma(first_pat.span, rt)?;
+ }
// If the next token is not a `|`,
// this is not an or-pattern and we should exit here.
@@ -111,7 +113,9 @@ impl<'a> Parser<'a> {
// This complicated procedure is done purely for diagnostics UX.
// Check if the user wrote `foo:bar` instead of `foo::bar`.
- let first_pat = self.maybe_recover_colon_colon_in_pat_typo(first_pat, ra, expected);
+ if ra == RecoverColon::Yes {
+ first_pat = self.maybe_recover_colon_colon_in_pat_typo(first_pat, expected);
+ }
if let Some(leading_vert_span) = leading_vert_span {
// If there was a leading vert, treat this as an or-pattern. This improves
@@ -139,7 +143,9 @@ impl<'a> Parser<'a> {
err.span_label(lo, WHILE_PARSING_OR_MSG);
err
})?;
- self.maybe_recover_unexpected_comma(pat.span, rc, rt)?;
+ if rc == RecoverComma::Yes {
+ self.maybe_recover_unexpected_comma(pat.span, rt)?;
+ }
pats.push(pat);
}
let or_pattern_span = lo.to(self.prev_token.span);
@@ -408,7 +414,7 @@ impl<'a> Parser<'a> {
};
let pat = self.mk_pat(lo.to(self.prev_token.span), pat);
- let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
+ let pat = self.maybe_recover_from_bad_qpath(pat)?;
let pat = self.recover_intersection_pat(pat)?;
if !allow_range_pat {
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 27a6a487474..7907ec44e98 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -180,7 +180,7 @@ impl<'a> Parser<'a> {
} else {
// Since none of the above applied, this is an expression statement macro.
let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new());
- let e = self.maybe_recover_from_bad_qpath(e, true)?;
+ let e = self.maybe_recover_from_bad_qpath(e)?;
let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
StmtKind::Expr(e)
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index fb3f5eb3f9f..dee025cfd3c 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -312,13 +312,18 @@ impl<'a> Parser<'a> {
};
let span = lo.to(self.prev_token.span);
- let ty = self.mk_ty(span, kind);
+ let mut ty = self.mk_ty(span, kind);
// Try to recover from use of `+` with incorrect priority.
- self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty);
- self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
- let ty = self.maybe_recover_from_question_mark(ty, recover_question_mark);
- self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)
+ if matches!(allow_plus, AllowPlus::Yes) {
+ self.maybe_recover_from_bad_type_plus(&ty)?;
+ } else {
+ self.maybe_report_ambiguous_plus(impl_dyn_multi, &ty);
+ }
+ if let RecoverQuestionMark::Yes = recover_question_mark {
+ ty = self.maybe_recover_from_question_mark(ty);
+ }
+ if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
}
/// Parses either:
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index c199cff2038..b1fe418f687 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1839,9 +1839,18 @@ impl<'a> Resolver<'a> {
)),
)
} else if self.session.edition() == Edition::Edition2015 {
- (format!("maybe a missing crate `{}`?", ident), None)
+ (
+ format!("maybe a missing crate `{ident}`?"),
+ Some((
+ vec![],
+ format!(
+ "consider adding `extern crate {ident}` to use the `{ident}` crate"
+ ),
+ Applicability::MaybeIncorrect,
+ )),
+ )
} else {
- (format!("could not find `{}` in the crate root", ident), None)
+ (format!("could not find `{ident}` in the crate root"), None)
}
} else if i > 0 {
let parent = path[i - 1].ident.name;
@@ -1852,7 +1861,7 @@ impl<'a> Resolver<'a> {
"the list of imported crates".to_owned()
}
kw::PathRoot | kw::Crate => "the crate root".to_owned(),
- _ => format!("`{}`", parent),
+ _ => format!("`{parent}`"),
};
let mut msg = format!("could not find `{}` in {}", ident, parent);
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index a8c8c674d2d..de83a3a5932 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -475,6 +475,10 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
}
if let Some((suggestions, msg, applicability)) = err.suggestion {
+ if suggestions.is_empty() {
+ diag.help(&msg);
+ continue;
+ }
diag.multipart_suggestion(&msg, suggestions, applicability);
}
}
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index a71621a4d52..641b915f373 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -145,15 +145,28 @@ impl<'tcx> ProjectionCandidateSet<'tcx> {
}
}
-/// Takes the place of a
+/// States returned from `poly_project_and_unify_type`. Takes the place
+/// of the old return type, which was:
+/// ```ignore (not-rust)
/// Result<
/// Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
/// MismatchedProjectionTypes<'tcx>,
/// >
+/// ```
pub(super) enum ProjectAndUnifyResult<'tcx> {
+ /// The projection bound holds subject to the given obligations. If the
+ /// projection cannot be normalized because the required trait bound does
+ /// not hold, this is returned, with `obligations` being a predicate that
+ /// cannot be proven.
Holds(Vec<PredicateObligation<'tcx>>),
+ /// The projection cannot be normalized due to ambiguity. Resolving some
+ /// inference variables in the projection may fix this.
FailedNormalization,
+ /// The project cannot be normalized because `poly_project_and_unify_type`
+ /// is called recursively while normalizing the same projection.
Recursive,
+ // the projection can be normalized, but is not equal to the expected type.
+ // Returns the type error that arose from the mismatch.
MismatchedProjectionTypes(MismatchedProjectionTypes<'tcx>),
}
@@ -163,19 +176,6 @@ pub(super) enum ProjectAndUnifyResult<'tcx> {
/// ```
/// If successful, this may result in additional obligations. Also returns
/// the projection cache key used to track these additional obligations.
-///
-/// ## Returns
-///
-/// - `Err(_)`: the projection can be normalized, but is not equal to the
-/// expected type.
-/// - `Ok(Err(InProgress))`: this is called recursively while normalizing
-/// the same projection.
-/// - `Ok(Ok(None))`: The projection cannot be normalized due to ambiguity
-/// (resolving some inference variables in the projection may fix this).
-/// - `Ok(Ok(Some(obligations)))`: The projection bound holds subject to
-/// the given obligations. If the projection cannot be normalized because
-/// the required trait bound doesn't hold this returned with `obligations`
-/// being a predicate that cannot be proven.
#[instrument(level = "debug", skip(selcx))]
pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 0379b16334c..2ce2a44d3db 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -81,10 +81,17 @@ pub fn trait_obligations<'a, 'tcx>(
body_id: hir::HirId,
trait_ref: &ty::TraitRef<'tcx>,
span: Span,
- item: Option<&'tcx hir::Item<'tcx>>,
+ item: &'tcx hir::Item<'tcx>,
) -> Vec<traits::PredicateObligation<'tcx>> {
- let mut wf =
- WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth: 0, item };
+ let mut wf = WfPredicates {
+ infcx,
+ param_env,
+ body_id,
+ span,
+ out: vec![],
+ recursion_depth: 0,
+ item: Some(item),
+ };
wf.compute_trait_ref(trait_ref, Elaborate::All);
debug!(obligations = ?wf.out);
wf.normalize()
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 4e54d554c6e..0e198907c8d 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -978,45 +978,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
label_span_not_found(&mut err);
}
- if let SelfSource::MethodCall(expr) = source
- && let Some((fields, substs)) = self.get_field_candidates(span, actual)
- {
- let call_expr =
- self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
- for candidate_field in fields.iter() {
- if let Some(field_path) = self.check_for_nested_field_satisfying(
- span,
- &|_, field_ty| {
- self.lookup_probe(
- span,
- item_name,
- field_ty,
- call_expr,
- ProbeScope::AllTraits,
- )
- .is_ok()
- },
- candidate_field,
- substs,
- vec![],
- self.tcx.parent_module(expr.hir_id).to_def_id(),
- ) {
- let field_path_str = field_path
- .iter()
- .map(|id| id.name.to_ident_string())
- .collect::<Vec<String>>()
- .join(".");
- debug!("field_path_str: {:?}", field_path_str);
+ self.check_for_field_method(&mut err, source, span, actual, item_name);
- err.span_suggestion_verbose(
- item_name.span.shrink_to_lo(),
- "one of the expressions' fields has a method of the same name",
- format!("{field_path_str}."),
- Applicability::MaybeIncorrect,
- );
- }
- }
- }
+ self.check_for_unwrap_self(&mut err, source, span, actual, item_name);
bound_spans.sort();
bound_spans.dedup();
@@ -1343,6 +1307,145 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false
}
+ fn check_for_field_method(
+ &self,
+ err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+ source: SelfSource<'tcx>,
+ span: Span,
+ actual: Ty<'tcx>,
+ item_name: Ident,
+ ) {
+ if let SelfSource::MethodCall(expr) = source
+ && let Some((fields, substs)) = self.get_field_candidates(span, actual)
+ {
+ let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
+ for candidate_field in fields.iter() {
+ if let Some(field_path) = self.check_for_nested_field_satisfying(
+ span,
+ &|_, field_ty| {
+ self.lookup_probe(
+ span,
+ item_name,
+ field_ty,
+ call_expr,
+ ProbeScope::AllTraits,
+ )
+ .is_ok()
+ },
+ candidate_field,
+ substs,
+ vec![],
+ self.tcx.parent_module(expr.hir_id).to_def_id(),
+ ) {
+ let field_path_str = field_path
+ .iter()
+ .map(|id| id.name.to_ident_string())
+ .collect::<Vec<String>>()
+ .join(".");
+ debug!("field_path_str: {:?}", field_path_str);
+
+ err.span_suggestion_verbose(
+ item_name.span.shrink_to_lo(),
+ "one of the expressions' fields has a method of the same name",
+ format!("{field_path_str}."),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
+ }
+ }
+
+ fn check_for_unwrap_self(
+ &self,
+ err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>,
+ source: SelfSource<'tcx>,
+ span: Span,
+ actual: Ty<'tcx>,
+ item_name: Ident,
+ ) {
+ let tcx = self.tcx;
+ let SelfSource::MethodCall(expr) = source else { return; };
+ let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id));
+
+ let ty::Adt(kind, substs) = actual.kind() else { return; };
+ if !kind.is_enum() {
+ return;
+ }
+
+ let matching_variants: Vec<_> = kind
+ .variants()
+ .iter()
+ .flat_map(|variant| {
+ let [field] = &variant.fields[..] else { return None; };
+ let field_ty = field.ty(tcx, substs);
+
+ // Skip `_`, since that'll just lead to ambiguity.
+ if self.resolve_vars_if_possible(field_ty).is_ty_var() {
+ return None;
+ }
+
+ self.lookup_probe(span, item_name, field_ty, call_expr, ProbeScope::AllTraits)
+ .ok()
+ .map(|pick| (variant, field, pick))
+ })
+ .collect();
+
+ let ret_ty_matches = |diagnostic_item| {
+ if let Some(ret_ty) = self
+ .ret_coercion
+ .as_ref()
+ .map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty()))
+ && let ty::Adt(kind, _) = ret_ty.kind()
+ && tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did())
+ {
+ true
+ } else {
+ false
+ }
+ };
+
+ match &matching_variants[..] {
+ [(_, field, pick)] => {
+ let self_ty = field.ty(tcx, substs);
+ err.span_note(
+ tcx.def_span(pick.item.def_id),
+ &format!("the method `{item_name}` exists on the type `{self_ty}`"),
+ );
+ let (article, kind, variant, question) =
+ if Some(kind.did()) == tcx.get_diagnostic_item(sym::Result) {
+ ("a", "Result", "Err", ret_ty_matches(sym::Result))
+ } else if Some(kind.did()) == tcx.get_diagnostic_item(sym::Option) {
+ ("an", "Option", "None", ret_ty_matches(sym::Option))
+ } else {
+ return;
+ };
+ if question {
+ err.span_suggestion_verbose(
+ expr.span.shrink_to_hi(),
+ format!(
+ "use the `?` operator to extract the `{self_ty}` value, propagating \
+ {article} `{kind}::{variant}` value to the caller"
+ ),
+ "?".to_owned(),
+ Applicability::MachineApplicable,
+ );
+ } else {
+ err.span_suggestion_verbose(
+ expr.span.shrink_to_hi(),
+ format!(
+ "consider using `{kind}::expect` to unwrap the `{self_ty}` value, \
+ panicking if the value is {article} `{kind}::{variant}`"
+ ),
+ ".expect(\"REASON\")".to_owned(),
+ Applicability::HasPlaceholders,
+ );
+ }
+ }
+ // FIXME(compiler-errors): Support suggestions for other matching enum variants
+ _ => {}
+ }
+ }
+
pub(crate) fn note_unmet_impls_on_type(
&self,
err: &mut Diagnostic,
@@ -1662,13 +1765,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "),
(self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"),
] {
- match self.lookup_probe(
- span,
- item_name,
- *rcvr_ty,
- rcvr,
- crate::check::method::probe::ProbeScope::AllTraits,
- ) {
+ match self.lookup_probe(span, item_name, *rcvr_ty, rcvr, ProbeScope::AllTraits) {
Ok(pick) => {
// If the method is defined for the receiver we have, it likely wasn't `use`d.
// We point at the method, but we just skip the rest of the check for arbitrary
@@ -1700,13 +1797,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Arc), "Arc::new"),
(self.tcx.mk_diagnostic_item(*rcvr_ty, sym::Rc), "Rc::new"),
] {
- if let Some(new_rcvr_t) = *rcvr_ty && let Ok(pick) = self.lookup_probe(
- span,
- item_name,
- new_rcvr_t,
- rcvr,
- crate::check::method::probe::ProbeScope::AllTraits,
- ) {
+ if let Some(new_rcvr_t) = *rcvr_ty
+ && let Ok(pick) = self.lookup_probe(
+ span,
+ item_name,
+ new_rcvr_t,
+ rcvr,
+ ProbeScope::AllTraits,
+ )
+ {
debug!("try_alt_rcvr: pick candidate {:?}", pick);
let did = Some(pick.item.container.id());
// We don't want to suggest a container type when the missing
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index a6c7573b787..20ef97c085f 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -1228,7 +1228,7 @@ fn check_impl<'tcx>(
fcx.body_id,
&trait_ref,
ast_trait_ref.path.span,
- Some(item),
+ item,
);
debug!(?obligations);
for obligation in obligations {
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 4b6f80ce57a..7e3fefe4502 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -161,38 +161,23 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
// We've encountered an `AnonConst` in some path, so we need to
// figure out which generic parameter it corresponds to and return
// the relevant type.
- let filtered = path.segments.iter().find_map(|seg| {
- seg.args?
- .args
+ let Some((arg_index, segment)) = path.segments.iter().find_map(|seg| {
+ let args = seg.args?;
+ args.args
+ .iter()
+ .filter(|arg| arg.is_ty_or_const())
+ .position(|arg| arg.id() == hir_id)
+ .map(|index| (index, seg)).or_else(|| args.bindings
.iter()
- .filter(|arg| arg.is_ty_or_const())
- .position(|arg| arg.id() == hir_id)
- .map(|index| (index, seg))
- });
-
- // FIXME(associated_const_generics): can we blend this with iteration above?
- let (arg_index, segment) = match filtered {
- None => {
- let binding_filtered = path.segments.iter().find_map(|seg| {
- seg.args?
- .bindings
- .iter()
- .filter_map(TypeBinding::opt_const)
- .position(|ct| ct.hir_id == hir_id)
- .map(|idx| (idx, seg))
- });
- match binding_filtered {
- Some(inner) => inner,
- None => {
- tcx.sess.delay_span_bug(
- tcx.def_span(def_id),
- "no arg matching AnonConst in path",
- );
- return None;
- }
- }
- }
- Some(inner) => inner,
+ .filter_map(TypeBinding::opt_const)
+ .position(|ct| ct.hir_id == hir_id)
+ .map(|idx| (idx, seg)))
+ }) else {
+ tcx.sess.delay_span_bug(
+ tcx.def_span(def_id),
+ "no arg matching AnonConst in path",
+ );
+ return None;
};
// Try to use the segment resolution if it is valid, otherwise we
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 20ef834eaee..caa629cf4e6 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -770,10 +770,14 @@ impl<T> BTreeSet<T> {
/// Adds a value to the set.
///
- /// If the set did not have an equal element present, `true` is returned.
+ /// Returns whether the value was newly inserted. That is:
///
- /// If the set did have an equal element present, `false` is returned, and
- /// the entry is not updated. See the [module-level documentation] for more.
+ /// - If the set did not previously contain an equal value, `true` is
+ /// returned.
+ /// - If the set already contained an equal value, `false` is returned, and
+ /// the entry is not updated.
+ ///
+ /// See the [module-level documentation] for more.
///
/// [module-level documentation]: index.html#insert-and-complex-keys
///
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 45947c4f4a5..33cffa643e4 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2495,6 +2495,7 @@ impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
impl<T, A: Allocator> ops::Deref for Vec<T, A> {
type Target = [T];
+ #[inline]
fn deref(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
}
@@ -2502,6 +2503,7 @@ impl<T, A: Allocator> ops::Deref for Vec<T, A> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T, A: Allocator> ops::DerefMut for Vec<T, A> {
+ #[inline]
fn deref_mut(&mut self) -> &mut [T] {
unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
}
diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs
index df0e7431f1f..a888ced49b3 100644
--- a/library/core/src/num/dec2flt/mod.rs
+++ b/library/core/src/num/dec2flt/mod.rs
@@ -126,7 +126,6 @@ macro_rules! from_str_float_impl {
/// ```txt
/// Float ::= Sign? ( 'inf' | 'infinity' | 'nan' | Number )
/// Number ::= ( Digit+ |
- /// '.' Digit* |
/// Digit+ '.' Digit* |
/// Digit* '.' Digit+ ) Exp?
/// Exp ::= 'e' Sign? Digit+
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 1aaa274a054..1fbf592c232 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1622,6 +1622,122 @@ impl<T> *mut [T] {
metadata(self)
}
+ /// Returns `true` if the raw slice has a length of 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(slice_ptr_len)]
+ ///
+ /// let mut a = [1, 2, 3];
+ /// let ptr = &mut a as *mut [_];
+ /// assert!(!ptr.is_empty());
+ /// ```
+ #[inline(always)]
+ #[unstable(feature = "slice_ptr_len", issue = "71146")]
+ #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
+ pub const fn is_empty(self) -> bool {
+ self.len() == 0
+ }
+
+ /// Divides one mutable raw slice into two at an index.
+ ///
+ /// The first will contain all indices from `[0, mid)` (excluding
+ /// the index `mid` itself) and the second will contain all
+ /// indices from `[mid, len)` (excluding the index `len` itself).
+ ///
+ /// # Panics
+ ///
+ /// Panics if `mid > len`.
+ ///
+ /// # Safety
+ ///
+ /// `mid` must be [in-bounds] of the underlying [allocated object].
+ /// Which means `self` must be dereferenceable and span a single allocation
+ /// that is at least `mid * size_of::<T>()` bytes long. Not upholding these
+ /// requirements is *[undefined behavior]* even if the resulting pointers are not used.
+ ///
+ /// Since `len` being in-bounds it is not a safety invariant of `*mut [T]` the
+ /// safety requirements of this method are the same as for [`split_at_mut_unchecked`].
+ /// The explicit bounds check is only as useful as `len` is correct.
+ ///
+ /// [`split_at_mut_unchecked`]: #method.split_at_mut_unchecked
+ /// [in-bounds]: #method.add
+ /// [allocated object]: crate::ptr#allocated-object
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(raw_slice_split)]
+ /// #![feature(slice_ptr_get)]
+ ///
+ /// let mut v = [1, 0, 3, 0, 5, 6];
+ /// let ptr = &mut v as *mut [_];
+ /// unsafe {
+ /// let (left, right) = ptr.split_at_mut(2);
+ /// assert_eq!(&*left, [1, 0]);
+ /// assert_eq!(&*right, [3, 0, 5, 6]);
+ /// }
+ /// ```
+ #[inline(always)]
+ #[track_caller]
+ #[unstable(feature = "raw_slice_split", issue = "95595")]
+ pub unsafe fn split_at_mut(self, mid: usize) -> (*mut [T], *mut [T]) {
+ assert!(mid <= self.len());
+ // SAFETY: The assert above is only a safety-net as long as `self.len()` is correct
+ // The actual safety requirements of this function are the same as for `split_at_mut_unchecked`
+ unsafe { self.split_at_mut_unchecked(mid) }
+ }
+
+ /// Divides one mutable raw slice into two at an index, without doing bounds checking.
+ ///
+ /// The first will contain all indices from `[0, mid)` (excluding
+ /// the index `mid` itself) and the second will contain all
+ /// indices from `[mid, len)` (excluding the index `len` itself).
+ ///
+ /// # Safety
+ ///
+ /// `mid` must be [in-bounds] of the underlying [allocated object].
+ /// Which means `self` must be dereferenceable and span a single allocation
+ /// that is at least `mid * size_of::<T>()` bytes long. Not upholding these
+ /// requirements is *[undefined behavior]* even if the resulting pointers are not used.
+ ///
+ /// [in-bounds]: #method.add
+ /// [out-of-bounds index]: #method.add
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(raw_slice_split)]
+ ///
+ /// let mut v = [1, 0, 3, 0, 5, 6];
+ /// // scoped to restrict the lifetime of the borrows
+ /// unsafe {
+ /// let ptr = &mut v as *mut [_];
+ /// let (left, right) = ptr.split_at_mut_unchecked(2);
+ /// assert_eq!(&*left, [1, 0]);
+ /// assert_eq!(&*right, [3, 0, 5, 6]);
+ /// (&mut *left)[1] = 2;
+ /// (&mut *right)[1] = 4;
+ /// }
+ /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+ /// ```
+ #[inline(always)]
+ #[unstable(feature = "raw_slice_split", issue = "95595")]
+ pub unsafe fn split_at_mut_unchecked(self, mid: usize) -> (*mut [T], *mut [T]) {
+ let len = self.len();
+ let ptr = self.as_mut_ptr();
+
+ // SAFETY: Caller must pass a valid pointer and an index that is in-bounds.
+ let tail = unsafe { ptr.add(mid) };
+ (
+ crate::ptr::slice_from_raw_parts_mut(ptr, mid),
+ crate::ptr::slice_from_raw_parts_mut(tail, len - mid),
+ )
+ }
+
/// Returns a raw pointer to the slice's buffer.
///
/// This is equivalent to casting `self` to `*mut T`, but more type-safe.
@@ -1645,9 +1761,10 @@ impl<T> *mut [T] {
/// Returns a raw pointer to an element or subslice, without doing bounds
/// checking.
///
- /// Calling this method with an out-of-bounds index or when `self` is not dereferenceable
+ /// Calling this method with an [out-of-bounds index] or when `self` is not dereferenceable
/// is *[undefined behavior]* even if the resulting pointer is not used.
///
+ /// [out-of-bounds index]: #method.add
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
///
/// # Examples
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 95506fc1eb9..229e546e085 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core" }
libc = { version = "0.2.126", default-features = false, features = ['rustc-dep-of-std'] }
-compiler_builtins = { version = "0.1.71" }
+compiler_builtins = { version = "0.1.73" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }
hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] }
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 4ec423eb27f..11ccdd9ea1c 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -896,6 +896,119 @@ where
self.base.get_key_value(k)
}
+ /// Attempts to get mutable references to `N` values in the map at once.
+ ///
+ /// Returns an array of length `N` with the results of each query. For soundness, at most one
+ /// mutable reference will be returned to any value. `None` will be returned if any of the
+ /// keys are duplicates or missing.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(map_many_mut)]
+ /// use std::collections::HashMap;
+ ///
+ /// let mut libraries = HashMap::new();
+ /// libraries.insert("Bodleian Library".to_string(), 1602);
+ /// libraries.insert("Athenæum".to_string(), 1807);
+ /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
+ /// libraries.insert("Library of Congress".to_string(), 1800);
+ ///
+ /// let got = libraries.get_many_mut([
+ /// "Athenæum",
+ /// "Library of Congress",
+ /// ]);
+ /// assert_eq!(
+ /// got,
+ /// Some([
+ /// &mut 1807,
+ /// &mut 1800,
+ /// ]),
+ /// );
+ ///
+ /// // Missing keys result in None
+ /// let got = libraries.get_many_mut([
+ /// "Athenæum",
+ /// "New York Public Library",
+ /// ]);
+ /// assert_eq!(got, None);
+ ///
+ /// // Duplicate keys result in None
+ /// let got = libraries.get_many_mut([
+ /// "Athenæum",
+ /// "Athenæum",
+ /// ]);
+ /// assert_eq!(got, None);
+ /// ```
+ #[inline]
+ #[unstable(feature = "map_many_mut", issue = "97601")]
+ pub fn get_many_mut<Q: ?Sized, const N: usize>(&mut self, ks: [&Q; N]) -> Option<[&'_ mut V; N]>
+ where
+ K: Borrow<Q>,
+ Q: Hash + Eq,
+ {
+ self.base.get_many_mut(ks)
+ }
+
+ /// Attempts to get mutable references to `N` values in the map at once, without validating that
+ /// the values are unique.
+ ///
+ /// Returns an array of length `N` with the results of each query. `None` will be returned if
+ /// any of the keys are missing.
+ ///
+ /// For a safe alternative see [`get_many_mut`](Self::get_many_mut).
+ ///
+ /// # Safety
+ ///
+ /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
+ /// references are not used.
+ ///
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(map_many_mut)]
+ /// use std::collections::HashMap;
+ ///
+ /// let mut libraries = HashMap::new();
+ /// libraries.insert("Bodleian Library".to_string(), 1602);
+ /// libraries.insert("Athenæum".to_string(), 1807);
+ /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
+ /// libraries.insert("Library of Congress".to_string(), 1800);
+ ///
+ /// let got = libraries.get_many_mut([
+ /// "Athenæum",
+ /// "Library of Congress",
+ /// ]);
+ /// assert_eq!(
+ /// got,
+ /// Some([
+ /// &mut 1807,
+ /// &mut 1800,
+ /// ]),
+ /// );
+ ///
+ /// // Missing keys result in None
+ /// let got = libraries.get_many_mut([
+ /// "Athenæum",
+ /// "New York Public Library",
+ /// ]);
+ /// assert_eq!(got, None);
+ /// ```
+ #[inline]
+ #[unstable(feature = "map_many_mut", issue = "97601")]
+ pub unsafe fn get_many_unchecked_mut<Q: ?Sized, const N: usize>(
+ &mut self,
+ ks: [&Q; N],
+ ) -> Option<[&'_ mut V; N]>
+ where
+ K: Borrow<Q>,
+ Q: Hash + Eq,
+ {
+ self.base.get_many_unchecked_mut(ks)
+ }
+
/// Returns `true` if the map contains a value for the specified key.
///
/// The key may be any borrowed form of the map's key type, but
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index da0572047ec..19428fe9a23 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -858,9 +858,10 @@ where
/// Adds a value to the set.
///
- /// If the set did not have this value present, `true` is returned.
+ /// Returns whether the value was newly inserted. That is:
///
- /// If the set did have this value present, `false` is returned.
+ /// - If the set did not previously contain this value, `true` is returned.
+ /// - If the set already contained this value, `false` is returned.
///
/// # Examples
///
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 1e434458dce..4605793d0df 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1667,6 +1667,10 @@ impl Type {
matches!(self, Type::Generic(_))
}
+ pub(crate) fn is_impl_trait(&self) -> bool {
+ matches!(self, Type::ImplTrait(_))
+ }
+
pub(crate) fn is_primitive(&self) -> bool {
self.primitive_type().is_some()
}
diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs
index 2367bde0167..9f26ccc74d1 100644
--- a/src/librustdoc/formats/mod.rs
+++ b/src/librustdoc/formats/mod.rs
@@ -7,6 +7,7 @@ use rustc_hir::def_id::DefId;
pub(crate) use renderer::{run_format, FormatRenderer};
use crate::clean::{self, ItemId};
+use cache::Cache;
/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
/// impl.
@@ -60,4 +61,28 @@ impl Impl {
}
}
}
+
+ // Returns true if this is an implementation on a "local" type, meaning:
+ // the type is in the current crate, or the type and the trait are both
+ // re-exported by the current crate.
+ pub(crate) fn is_on_local_type(&self, cache: &Cache) -> bool {
+ let for_type = &self.inner_impl().for_;
+ if let Some(for_type_did) = for_type.def_id(cache) {
+ // The "for" type is local if it's in the paths for the current crate.
+ if cache.paths.contains_key(&for_type_did) {
+ return true;
+ }
+ if let Some(trait_did) = self.trait_did() {
+ // The "for" type and the trait are from the same crate. That could
+ // be different from the current crate, for instance when both were
+ // re-exported from some other crate. But they are local with respect to
+ // each other.
+ if for_type_did.krate == trait_did.krate {
+ return true;
+ }
+ }
+ return false;
+ };
+ true
+ }
}
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index b8d6b340b14..0b801a20995 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2285,9 +2285,7 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
let mut res = implementors
.iter()
- .filter(|i| {
- i.inner_impl().for_.def_id(cache).map_or(false, |d| !cache.paths.contains_key(&d))
- })
+ .filter(|i| !i.is_on_local_type(cache))
.filter_map(|i| extract_for_impl_name(&i.impl_item, cx))
.collect::<Vec<_>>();
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index dcf36b5e865..8683e6dfcd9 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -822,9 +822,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
}
}
- let (local, foreign) = implementors.iter().partition::<Vec<_>, _>(|i| {
- i.inner_impl().for_.def_id(cache).map_or(true, |d| cache.paths.contains_key(&d))
- });
+ let (local, foreign) =
+ implementors.iter().partition::<Vec<_>, _>(|i| i.is_on_local_type(cache));
let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) =
local.iter().partition(|i| i.inner_impl().kind.is_auto());
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index 25c70f0808c..9f302cc2566 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -226,17 +226,17 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
Some(path.segments.last().unwrap().name)
}
// We return an empty name because we don't care about the generic name itself.
- clean::Generic(_) => Some(kw::Empty),
+ clean::Generic(_) | clean::ImplTrait(_) => Some(kw::Empty),
clean::Primitive(ref p) => Some(p.as_sym()),
- clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_),
+ clean::BorrowedRef { ref type_, .. } | clean::RawPointer(_, ref type_) => {
+ get_index_type_name(type_)
+ }
clean::BareFunction(_)
| clean::Tuple(_)
| clean::Slice(_)
| clean::Array(_, _)
- | clean::RawPointer(_, _)
| clean::QPath { .. }
- | clean::Infer
- | clean::ImplTrait(_) => None,
+ | clean::Infer => None,
}
}
@@ -264,10 +264,12 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>(
mut generics: Vec<TypeWithKind>,
cache: &Cache,
) {
- let is_full_generic = ty.is_full_generic();
+ // generics and impl trait are both identified by their generics,
+ // rather than a type name itself
+ let anonymous = ty.is_full_generic() || ty.is_impl_trait();
let generics_empty = generics.is_empty();
- if is_full_generic {
+ if anonymous {
if generics_empty {
// This is a type parameter with no trait bounds (for example: `T` in
// `fn f<T>(p: T)`, so not useful for the rustdoc search because we would end up
@@ -318,7 +320,7 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>(
if index_ty.name.as_ref().map(|s| s.is_empty() && generics_empty).unwrap_or(true) {
return;
}
- if is_full_generic {
+ if anonymous {
// We remove the name of the full generic because we have no use for it.
index_ty.name = Some(String::new());
res.push(TypeWithKind::from((index_ty, ItemType::Generic)));
@@ -398,6 +400,23 @@ fn add_generics_and_bounds_as_types<'tcx, 'a>(
}
insert_ty(res, tcx, arg.clone(), ty_generics, cache);
}
+ } else if let Type::ImplTrait(ref bounds) = *arg {
+ let mut ty_generics = Vec::new();
+ for bound in bounds {
+ if let Some(path) = bound.get_trait_path() {
+ let ty = Type::Path { path };
+ add_generics_and_bounds_as_types(
+ self_,
+ generics,
+ &ty,
+ tcx,
+ recurse + 1,
+ &mut ty_generics,
+ cache,
+ );
+ }
+ }
+ insert_ty(res, tcx, arg.clone(), ty_generics, cache);
} else {
// This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
// looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't.
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index aa7028247be..6ea33d763b1 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -9,7 +9,7 @@ use crate::visit::DocVisitor;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::DefId;
-use rustc_middle::ty::DefIdTree;
+use rustc_middle::ty::{self, DefIdTree};
use rustc_span::symbol::sym;
pub(crate) const COLLECT_TRAIT_IMPLS: Pass = Pass {
@@ -81,8 +81,35 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
// Do not calculate blanket impl list for docs that are not going to be rendered.
// While the `impl` blocks themselves are only in `libcore`, the module with `doc`
// attached is directly included in `libstd` as well.
+ let tcx = cx.tcx;
if did.is_local() {
- for def_id in prim.impls(cx.tcx) {
+ for def_id in prim.impls(tcx).filter(|def_id| {
+ // Avoid including impl blocks with filled-in generics.
+ // https://github.com/rust-lang/rust/issues/94937
+ //
+ // FIXME(notriddle): https://github.com/rust-lang/rust/issues/97129
+ //
+ // This tactic of using inherent impl blocks for getting
+ // auto traits and blanket impls is a hack. What we really
+ // want is to check if `[T]` impls `Send`, which has
+ // nothing to do with the inherent impl.
+ //
+ // Rustdoc currently uses these `impl` block as a source of
+ // the `Ty`, as well as the `ParamEnv`, `SubstsRef`, and
+ // `Generics`. To avoid relying on the `impl` block, these
+ // things would need to be created from wholecloth, in a
+ // form that is valid for use in type inference.
+ let ty = tcx.type_of(def_id);
+ match ty.kind() {
+ ty::Slice(ty)
+ | ty::Ref(_, ty, _)
+ | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
+ matches!(ty.kind(), ty::Param(..))
+ }
+ ty::Tuple(tys) => tys.iter().all(|ty| matches!(ty.kind(), ty::Param(..))),
+ _ => true,
+ }
+ }) {
let impls = get_auto_trait_and_blanket_impls(cx, def_id);
new_items_external.extend(impls.filter(|i| cx.inlined.insert(i.item_id)));
}
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
index 4fdd4b2b4bb..84d72202d52 100644
--- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
@@ -21,7 +21,7 @@
// + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
// + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) }
_2 = &raw const (*_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
- _1 = move _2 as usize (PointerAddress); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:39
+ _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:39
StorageDead(_2); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:38: 7:39
StorageDead(_3); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:39: 7:40
StorageLive(_4); // scope 1 at $DIR/const_prop_fails_gracefully.rs:8:5: 8:12
diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
index 7eb34ed5469..04724b13ca6 100644
--- a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
@@ -17,7 +17,7 @@
// mir::Constant
// + span: $DIR/reify_fn_ptr.rs:4:13: 4:17
// + literal: Const { ty: fn() {main}, val: Value(Scalar(<ZST>)) }
- _2 = move _3 as usize (PointerAddress); // scope 0 at $DIR/reify_fn_ptr.rs:4:13: 4:26
+ _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:4:13: 4:26
StorageDead(_3); // scope 0 at $DIR/reify_fn_ptr.rs:4:25: 4:26
_1 = move _2 as *const fn() (Misc); // scope 0 at $DIR/reify_fn_ptr.rs:4:13: 4:41
StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:4:40: 4:41
diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff
index bf32245e300..2331f63ecdd 100644
--- a/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff
+++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff
@@ -19,12 +19,12 @@
StorageLive(_2); // scope 0 at $DIR/provenance_soundness.rs:8:9: 8:11
StorageLive(_3); // scope 0 at $DIR/provenance_soundness.rs:8:14: 8:15
_3 = _1; // scope 0 at $DIR/provenance_soundness.rs:8:14: 8:15
- _2 = move _3 as usize (PointerAddress); // scope 0 at $DIR/provenance_soundness.rs:8:14: 8:24
+ _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/provenance_soundness.rs:8:14: 8:24
StorageDead(_3); // scope 0 at $DIR/provenance_soundness.rs:8:23: 8:24
StorageLive(_4); // scope 1 at $DIR/provenance_soundness.rs:9:9: 9:11
StorageLive(_5); // scope 1 at $DIR/provenance_soundness.rs:9:14: 9:15
_5 = _1; // scope 1 at $DIR/provenance_soundness.rs:9:14: 9:15
- _4 = move _5 as isize (PointerAddress); // scope 1 at $DIR/provenance_soundness.rs:9:14: 9:24
+ _4 = move _5 as isize (PointerExposeAddress); // scope 1 at $DIR/provenance_soundness.rs:9:14: 9:24
StorageDead(_5); // scope 1 at $DIR/provenance_soundness.rs:9:23: 9:24
_0 = const (); // scope 0 at $DIR/provenance_soundness.rs:7:32: 10:2
StorageDead(_4); // scope 1 at $DIR/provenance_soundness.rs:10:1: 10:2
diff --git a/src/test/rustdoc-js/impl-trait.js b/src/test/rustdoc-js/impl-trait.js
new file mode 100644
index 00000000000..8d594bf8aea
--- /dev/null
+++ b/src/test/rustdoc-js/impl-trait.js
@@ -0,0 +1,51 @@
+// ignore-order
+
+const QUERY = [
+ 'Aaaaaaa -> i32',
+ 'Aaaaaaa -> Aaaaaaa',
+ 'Aaaaaaa -> usize',
+ '-> Aaaaaaa',
+ 'Aaaaaaa',
+];
+
+const EXPECTED = [
+ {
+ // Aaaaaaa -> i32
+ 'others': [
+ { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
+ ],
+ },
+ {
+ // Aaaaaaa -> Aaaaaaa
+ 'others': [
+ { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
+ ],
+ },
+ {
+ // Aaaaaaa -> usize
+ 'others': [],
+ },
+ {
+ // -> Aaaaaaa
+ 'others': [
+ { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
+ { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
+ { 'path': 'impl_trait', 'name': 'bbbbbbb' },
+ ],
+ },
+ {
+ // Aaaaaaa
+ 'others': [
+ { 'path': 'impl_trait', 'name': 'Aaaaaaa' },
+ ],
+ 'in_args': [
+ { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
+ { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
+ ],
+ 'returned': [
+ { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
+ { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
+ { 'path': 'impl_trait', 'name': 'bbbbbbb' },
+ ],
+ },
+];
diff --git a/src/test/rustdoc-js/impl-trait.rs b/src/test/rustdoc-js/impl-trait.rs
new file mode 100644
index 00000000000..fb8869b46f3
--- /dev/null
+++ b/src/test/rustdoc-js/impl-trait.rs
@@ -0,0 +1,21 @@
+pub trait Aaaaaaa {}
+
+impl Aaaaaaa for () {}
+
+pub fn bbbbbbb() -> impl Aaaaaaa {
+ ()
+}
+
+pub struct Ccccccc {}
+
+impl Ccccccc {
+ pub fn ddddddd(&self) -> impl Aaaaaaa {
+ ()
+ }
+ pub fn eeeeeee(&self, _x: impl Aaaaaaa) -> i32 {
+ 0
+ }
+ pub fn fffffff(&self, x: impl Aaaaaaa) -> impl Aaaaaaa {
+ x
+ }
+}
diff --git a/src/test/rustdoc-js/raw-pointer.js b/src/test/rustdoc-js/raw-pointer.js
new file mode 100644
index 00000000000..140b955ea71
--- /dev/null
+++ b/src/test/rustdoc-js/raw-pointer.js
@@ -0,0 +1,55 @@
+// ignore-order
+
+const QUERY = [
+ 'Aaaaaaa -> i32',
+ 'Aaaaaaa -> Aaaaaaa',
+ 'Aaaaaaa -> usize',
+ '-> Aaaaaaa',
+ 'Aaaaaaa',
+];
+
+const EXPECTED = [
+ {
+ // Aaaaaaa -> i32
+ 'others': [
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'eeeeeee' },
+ ],
+ },
+ {
+ // Aaaaaaa -> Aaaaaaa
+ 'others': [
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'fffffff' },
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'ggggggg' },
+ ],
+ },
+ {
+ // Aaaaaaa -> usize
+ 'others': [],
+ },
+ {
+ // -> Aaaaaaa
+ 'others': [
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'fffffff' },
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'ggggggg' },
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'ddddddd' },
+ { 'path': 'raw_pointer', 'name': 'bbbbbbb' },
+ ],
+ },
+ {
+ // Aaaaaaa
+ 'others': [
+ { 'path': 'raw_pointer', 'name': 'Aaaaaaa' },
+ ],
+ 'in_args': [
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'fffffff' },
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'ggggggg' },
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'eeeeeee' },
+ ],
+ 'returned': [
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'fffffff' },
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'ggggggg' },
+ { 'path': 'raw_pointer::Ccccccc', 'name': 'ddddddd' },
+ { 'path': 'raw_pointer', 'name': 'bbbbbbb' },
+ ],
+ },
+];
diff --git a/src/test/rustdoc-js/raw-pointer.rs b/src/test/rustdoc-js/raw-pointer.rs
new file mode 100644
index 00000000000..b8ace2e0b7d
--- /dev/null
+++ b/src/test/rustdoc-js/raw-pointer.rs
@@ -0,0 +1,24 @@
+use std::ptr;
+
+pub struct Aaaaaaa {}
+
+pub fn bbbbbbb() -> *const Aaaaaaa {
+ ptr::null()
+}
+
+pub struct Ccccccc {}
+
+impl Ccccccc {
+ pub fn ddddddd(&self) -> *const Aaaaaaa {
+ ptr::null()
+ }
+ pub fn eeeeeee(&self, _x: *const Aaaaaaa) -> i32 {
+ 0
+ }
+ pub fn fffffff(&self, x: *const Aaaaaaa) -> *const Aaaaaaa {
+ x
+ }
+ pub fn ggggggg(&self, x: *mut Aaaaaaa) -> *mut Aaaaaaa {
+ x
+ }
+}
diff --git a/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr
index b60ab6050d7..b54f8200666 100644
--- a/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr
+++ b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr
@@ -3,6 +3,8 @@ error[E0433]: failed to resolve: maybe a missing crate `unresolved_crate`?
|
LL | use unresolved_crate::module::Name;
| ^^^^^^^^^^^^^^^^ maybe a missing crate `unresolved_crate`?
+ |
+ = help: consider adding `extern crate unresolved_crate` to use the `unresolved_crate` crate
error: Compilation failed, aborting rustdoc
diff --git a/src/test/rustdoc-ui/issue-61732.stderr b/src/test/rustdoc-ui/issue-61732.stderr
index 82134224911..38fadaa4435 100644
--- a/src/test/rustdoc-ui/issue-61732.stderr
+++ b/src/test/rustdoc-ui/issue-61732.stderr
@@ -3,6 +3,8 @@ error[E0433]: failed to resolve: maybe a missing crate `r#mod`?
|
LL | pub(in crate::r#mod) fn main() {}
| ^^^^^ maybe a missing crate `r#mod`?
+ |
+ = help: consider adding `extern crate r#mod` to use the `r#mod` crate
error: Compilation failed, aborting rustdoc
diff --git a/src/test/rustdoc/inline_cross/auxiliary/implementors_inline.rs b/src/test/rustdoc/inline_cross/auxiliary/implementors_inline.rs
new file mode 100644
index 00000000000..b003fb357d0
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/auxiliary/implementors_inline.rs
@@ -0,0 +1,18 @@
+pub mod my_trait {
+ pub trait MyTrait {
+ fn my_fn(&self) -> Self;
+ }
+}
+
+pub mod prelude {
+ #[doc(inline)]
+ pub use crate::my_trait::MyTrait;
+}
+
+pub struct SomeStruct;
+
+impl my_trait::MyTrait for SomeStruct {
+ fn my_fn(&self) -> SomeStruct {
+ SomeStruct
+ }
+}
diff --git a/src/test/rustdoc/inline_cross/implementors-js.rs b/src/test/rustdoc/inline_cross/implementors-js.rs
new file mode 100644
index 00000000000..c79f05d8d3c
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/implementors-js.rs
@@ -0,0 +1,25 @@
+// aux-build:implementors_inline.rs
+// build-aux-docs
+// ignore-cross-compile
+
+extern crate implementors_inline;
+
+// @!has implementors/implementors_js/trait.MyTrait.js
+// @has implementors/implementors_inline/my_trait/trait.MyTrait.js
+// @!has implementors/implementors_inline/prelude/trait.MyTrait.js
+// @has implementors_inline/my_trait/trait.MyTrait.html
+// @has - '//script/@src' '../../implementors/implementors_inline/my_trait/trait.MyTrait.js'
+// @has implementors_js/trait.MyTrait.html
+// @has - '//script/@src' '../implementors/implementors_inline/my_trait/trait.MyTrait.js'
+/// When re-exporting this trait, the HTML will be inlined,
+/// but, vitally, the JavaScript will be located only at the
+/// one canonical path.
+pub use implementors_inline::prelude::MyTrait;
+
+pub struct OtherStruct;
+
+impl MyTrait for OtherStruct {
+ fn my_fn(&self) -> OtherStruct {
+ OtherStruct
+ }
+}
diff --git a/src/test/rustdoc/intra-doc/email-address.rs b/src/test/rustdoc/intra-doc/email-address.rs
index ae74fbbc892..24161c3bb48 100644
--- a/src/test/rustdoc/intra-doc/email-address.rs
+++ b/src/test/rustdoc/intra-doc/email-address.rs
@@ -1,8 +1,10 @@
-#![allow(rustdoc::broken_intra_doc_links)]
+#![forbid(rustdoc::broken_intra_doc_links)]
//! Email me at <hello@example.com>.
//! Email me at <hello-world@example.com>.
-//! Email me at <hello@localhost> (this warns but will still become a link).
+//! Email me at <hello@localhost>.
+//! Email me at <prim@i32>.
// @has email_address/index.html '//a[@href="mailto:hello@example.com"]' 'hello@example.com'
// @has email_address/index.html '//a[@href="mailto:hello-world@example.com"]' 'hello-world@example.com'
// @has email_address/index.html '//a[@href="mailto:hello@localhost"]' 'hello@localhost'
+// @has email_address/index.html '//a[@href="mailto:prim@i32"]' 'prim@i32'
diff --git a/src/test/rustdoc/issue-75588.rs b/src/test/rustdoc/issue-75588.rs
index ac97b94fb35..a8cb16ec34c 100644
--- a/src/test/rustdoc/issue-75588.rs
+++ b/src/test/rustdoc/issue-75588.rs
@@ -13,5 +13,5 @@ extern crate real_gimli;
// @!has foo/trait.Deref.html '//*[@id="impl-Deref-for-EndianSlice"]//h3[@class="code-header in-band"]' 'impl Deref for EndianSlice'
pub use realcore::Deref;
-// @has foo/trait.Join.html '//*[@id="impl-Join-for-Foo"]//h3[@class="code-header in-band"]' 'impl Join for Foo'
+// @has foo/trait.Join.html '//*[@id="impl-Join"]//h3[@class="code-header in-band"]' 'impl Join for Foo'
pub use realcore::Join;
diff --git a/src/test/rustdoc/primitive-slice-auto-trait.rs b/src/test/rustdoc/primitive-slice-auto-trait.rs
new file mode 100644
index 00000000000..b3f511bc1f1
--- /dev/null
+++ b/src/test/rustdoc/primitive-slice-auto-trait.rs
@@ -0,0 +1,14 @@
+// compile-flags: --crate-type lib --edition 2018
+
+#![crate_name = "foo"]
+#![feature(rustdoc_internals)]
+
+// @has foo/primitive.slice.html '//a[@class="primitive"]' 'slice'
+// @has - '//span[@class="in-band"]' 'Primitive Type slice'
+// @has - '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
+// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
+// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T] where T: Send'
+// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T] where T: Sync'
+#[doc(primitive = "slice")]
+/// this is a test!
+mod slice_prim {}
diff --git a/src/test/ui/attributes/field-attributes-vis-unresolved.stderr b/src/test/ui/attributes/field-attributes-vis-unresolved.stderr
index 41c3cea3021..43976254638 100644
--- a/src/test/ui/attributes/field-attributes-vis-unresolved.stderr
+++ b/src/test/ui/attributes/field-attributes-vis-unresolved.stderr
@@ -3,12 +3,16 @@ error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
|
LL | pub(in nonexistent) field: u8
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
+ |
+ = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate
error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
--> $DIR/field-attributes-vis-unresolved.rs:22:12
|
LL | pub(in nonexistent) u8
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
+ |
+ = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate
error: aborting due to 2 previous errors
diff --git a/src/test/ui/borrowck/issue-71546.rs b/src/test/ui/borrowck/issue-71546.rs
new file mode 100644
index 00000000000..943f7f86e55
--- /dev/null
+++ b/src/test/ui/borrowck/issue-71546.rs
@@ -0,0 +1,19 @@
+// Regression test for #71546.
+
+// ignore-compare-mode-nll
+// NLL stderr is different from the original one.
+
+pub fn serialize_as_csv<V>(value: &V) -> Result<String, &str>
+where
+ V: 'static,
+ for<'a> &'a V: IntoIterator,
+ for<'a> <&'a V as IntoIterator>::Item: ToString + 'static,
+{
+ let csv_str: String = value //~ ERROR: the associated type `<&'a V as IntoIterator>::Item` may not live long enough
+ .into_iter()
+ .map(|elem| elem.to_string())
+ .collect::<String>();
+ Ok(csv_str)
+}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/issue-71546.stderr b/src/test/ui/borrowck/issue-71546.stderr
new file mode 100644
index 00000000000..d479ca8f1d8
--- /dev/null
+++ b/src/test/ui/borrowck/issue-71546.stderr
@@ -0,0 +1,20 @@
+error[E0310]: the associated type `<&'a V as IntoIterator>::Item` may not live long enough
+ --> $DIR/issue-71546.rs:12:27
+ |
+LL | let csv_str: String = value
+ | ___________________________^
+LL | | .into_iter()
+LL | | .map(|elem| elem.to_string())
+ | |_____________________________________^
+ |
+ = help: consider adding an explicit lifetime bound `<&'a V as IntoIterator>::Item: 'static`...
+ = note: ...so that the type `<&'a V as IntoIterator>::Item` will meet its required lifetime bounds...
+note: ...that is required by this bound
+ --> $DIR/issue-71546.rs:10:55
+ |
+LL | for<'a> <&'a V as IntoIterator>::Item: ToString + 'static,
+ | ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr
index aff51ee9e2f..2eb3fd56783 100644
--- a/src/test/ui/codemap_tests/two_files.stderr
+++ b/src/test/ui/codemap_tests/two_files.stderr
@@ -5,6 +5,7 @@ LL | impl Bar for Baz { }
| ^^^ type aliases cannot be used as traits
|
help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` alias
+ --> $DIR/two_files_data.rs:5:1
|
LL | trait Bar = dyn Foo;
|
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-94287.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-94287.stderr
index c918651ba62..7390a007742 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-94287.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-94287.stderr
@@ -6,6 +6,7 @@ LL | If<{ FRAC <= 32 }>: True,
|
= note: the crate this constant originates from uses `#![feature(generic_const_exprs)]`
help: consider enabling this feature
+ --> $DIR/issue-94287.rs:1:1
|
LL | #![feature(generic_const_exprs)]
|
diff --git a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr
index 23dad2c16b2..570bbac2b21 100644
--- a/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr
+++ b/src/test/ui/editions/edition-keywords-2015-2018-expansion.stderr
@@ -6,6 +6,7 @@ LL | produces_async! {}
|
= note: this error originates in the macro `produces_async` (in Nightly builds, run with -Z macro-backtrace for more info)
help: escape `async` to use it as an identifier
+ --> $DIR/auxiliary/edition-kw-macro-2018.rs:7:19
|
LL | () => (pub fn r#async() {})
| ++
diff --git a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr
index 67f9aa60413..69f275746bd 100644
--- a/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr
+++ b/src/test/ui/editions/edition-keywords-2018-2018-expansion.stderr
@@ -6,6 +6,7 @@ LL | produces_async! {}
|
= note: this error originates in the macro `produces_async` (in Nightly builds, run with -Z macro-backtrace for more info)
help: escape `async` to use it as an identifier
+ --> $DIR/auxiliary/edition-kw-macro-2018.rs:7:19
|
LL | () => (pub fn r#async() {})
| ++
diff --git a/src/test/ui/error-codes/E0432.stderr b/src/test/ui/error-codes/E0432.stderr
index afb031c2252..ed9536f164e 100644
--- a/src/test/ui/error-codes/E0432.stderr
+++ b/src/test/ui/error-codes/E0432.stderr
@@ -3,6 +3,8 @@ error[E0432]: unresolved import `something`
|
LL | use something::Foo;
| ^^^^^^^^^ maybe a missing crate `something`?
+ |
+ = help: consider adding `extern crate something` to use the `something` crate
error: aborting due to previous error
diff --git a/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr b/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
index 2f4c220ee95..3bae23a4aaa 100644
--- a/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
+++ b/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
@@ -3,12 +3,16 @@ error[E0432]: unresolved import `core`
|
LL | use core::default;
| ^^^^ maybe a missing crate `core`?
+ |
+ = help: consider adding `extern crate core` to use the `core` crate
error[E0433]: failed to resolve: maybe a missing crate `core`?
--> $DIR/feature-gate-extern_absolute_paths.rs:4:19
|
LL | let _: u8 = ::core::default::Default();
| ^^^^ maybe a missing crate `core`?
+ |
+ = help: consider adding `extern crate core` to use the `core` crate
error: aborting due to 2 previous errors
diff --git a/src/test/ui/imports/import3.stderr b/src/test/ui/imports/import3.stderr
index 7bb413be59f..ca75c9c18bd 100644
--- a/src/test/ui/imports/import3.stderr
+++ b/src/test/ui/imports/import3.stderr
@@ -3,6 +3,8 @@ error[E0432]: unresolved import `main`
|
LL | use main::bar;
| ^^^^ maybe a missing crate `main`?
+ |
+ = help: consider adding `extern crate main` to use the `main` crate
error: aborting due to previous error
diff --git a/src/test/ui/imports/issue-1697.stderr b/src/test/ui/imports/issue-1697.stderr
index a76fd309914..019ef9ad56a 100644
--- a/src/test/ui/imports/issue-1697.stderr
+++ b/src/test/ui/imports/issue-1697.stderr
@@ -3,6 +3,8 @@ error[E0432]: unresolved import `unresolved`
|
LL | use unresolved::*;
| ^^^^^^^^^^ maybe a missing crate `unresolved`?
+ |
+ = help: consider adding `extern crate unresolved` to use the `unresolved` crate
error: aborting due to previous error
diff --git a/src/test/ui/imports/issue-33464.stderr b/src/test/ui/imports/issue-33464.stderr
index d3bf404c99a..c4e5c555899 100644
--- a/src/test/ui/imports/issue-33464.stderr
+++ b/src/test/ui/imports/issue-33464.stderr
@@ -3,18 +3,24 @@ error[E0432]: unresolved import `abc`
|
LL | use abc::one_el;
| ^^^ maybe a missing crate `abc`?
+ |
+ = help: consider adding `extern crate abc` to use the `abc` crate
error[E0432]: unresolved import `abc`
--> $DIR/issue-33464.rs:5:5
|
LL | use abc::{a, bbb, cccccc};
| ^^^ maybe a missing crate `abc`?
+ |
+ = help: consider adding `extern crate abc` to use the `abc` crate
error[E0432]: unresolved import `a_very_long_name`
--> $DIR/issue-33464.rs:7:5
|
LL | use a_very_long_name::{el, el2};
| ^^^^^^^^^^^^^^^^ maybe a missing crate `a_very_long_name`?
+ |
+ = help: consider adding `extern crate a_very_long_name` to use the `a_very_long_name` crate
error: aborting due to 3 previous errors
diff --git a/src/test/ui/imports/issue-36881.stderr b/src/test/ui/imports/issue-36881.stderr
index caf9d5d6d62..2e1b468603d 100644
--- a/src/test/ui/imports/issue-36881.stderr
+++ b/src/test/ui/imports/issue-36881.stderr
@@ -3,6 +3,8 @@ error[E0432]: unresolved import `issue_36881_aux`
|
LL | use issue_36881_aux::Foo;
| ^^^^^^^^^^^^^^^ maybe a missing crate `issue_36881_aux`?
+ |
+ = help: consider adding `extern crate issue_36881_aux` to use the `issue_36881_aux` crate
error: aborting due to previous error
diff --git a/src/test/ui/imports/issue-37887.stderr b/src/test/ui/imports/issue-37887.stderr
index 944d544098a..75185cad3b7 100644
--- a/src/test/ui/imports/issue-37887.stderr
+++ b/src/test/ui/imports/issue-37887.stderr
@@ -3,6 +3,8 @@ error[E0432]: unresolved import `libc`
|
LL | use libc::*;
| ^^^^ maybe a missing crate `libc`?
+ |
+ = help: consider adding `extern crate libc` to use the `libc` crate
error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
--> $DIR/issue-37887.rs:2:5
diff --git a/src/test/ui/imports/issue-53269.stderr b/src/test/ui/imports/issue-53269.stderr
index a0e7bf8b61f..29c7556dac4 100644
--- a/src/test/ui/imports/issue-53269.stderr
+++ b/src/test/ui/imports/issue-53269.stderr
@@ -3,6 +3,8 @@ error[E0432]: unresolved import `nonexistent_module`
|
LL | use nonexistent_module::mac;
| ^^^^^^^^^^^^^^^^^^ maybe a missing crate `nonexistent_module`?
+ |
+ = help: consider adding `extern crate nonexistent_module` to use the `nonexistent_module` crate
error[E0659]: `mac` is ambiguous
--> $DIR/issue-53269.rs:8:5
diff --git a/src/test/ui/imports/issue-55457.stderr b/src/test/ui/imports/issue-55457.stderr
index 07de3d95902..788fcc830ae 100644
--- a/src/test/ui/imports/issue-55457.stderr
+++ b/src/test/ui/imports/issue-55457.stderr
@@ -12,6 +12,8 @@ error[E0432]: unresolved import `non_existent`
|
LL | use non_existent::non_existent;
| ^^^^^^^^^^^^ maybe a missing crate `non_existent`?
+ |
+ = help: consider adding `extern crate non_existent` to use the `non_existent` crate
error: cannot determine resolution for the derive macro `NonExistent`
--> $DIR/issue-55457.rs:5:10
diff --git a/src/test/ui/imports/tool-mod-child.stderr b/src/test/ui/imports/tool-mod-child.stderr
index efab4f6a74f..6caf15bc724 100644
--- a/src/test/ui/imports/tool-mod-child.stderr
+++ b/src/test/ui/imports/tool-mod-child.stderr
@@ -3,24 +3,32 @@ error[E0433]: failed to resolve: maybe a missing crate `clippy`?
|
LL | use clippy::a::b;
| ^^^^^^ maybe a missing crate `clippy`?
+ |
+ = help: consider adding `extern crate clippy` to use the `clippy` crate
error[E0432]: unresolved import `clippy`
--> $DIR/tool-mod-child.rs:1:5
|
LL | use clippy::a;
| ^^^^^^ maybe a missing crate `clippy`?
+ |
+ = help: consider adding `extern crate clippy` to use the `clippy` crate
error[E0433]: failed to resolve: maybe a missing crate `rustdoc`?
--> $DIR/tool-mod-child.rs:5:5
|
LL | use rustdoc::a::b;
| ^^^^^^^ maybe a missing crate `rustdoc`?
+ |
+ = help: consider adding `extern crate rustdoc` to use the `rustdoc` crate
error[E0432]: unresolved import `rustdoc`
--> $DIR/tool-mod-child.rs:4:5
|
LL | use rustdoc::a;
| ^^^^^^^ maybe a missing crate `rustdoc`?
+ |
+ = help: consider adding `extern crate rustdoc` to use the `rustdoc` crate
error: aborting due to 4 previous errors
diff --git a/src/test/ui/imports/unresolved-imports-used.stderr b/src/test/ui/imports/unresolved-imports-used.stderr
index ddf36089339..73f9d1bfb6c 100644
--- a/src/test/ui/imports/unresolved-imports-used.stderr
+++ b/src/test/ui/imports/unresolved-imports-used.stderr
@@ -15,24 +15,32 @@ error[E0432]: unresolved import `foo`
|
LL | use foo::bar;
| ^^^ maybe a missing crate `foo`?
+ |
+ = help: consider adding `extern crate foo` to use the `foo` crate
error[E0432]: unresolved import `baz`
--> $DIR/unresolved-imports-used.rs:12:5
|
LL | use baz::*;
| ^^^ maybe a missing crate `baz`?
+ |
+ = help: consider adding `extern crate baz` to use the `baz` crate
error[E0432]: unresolved import `foo2`
--> $DIR/unresolved-imports-used.rs:14:5
|
LL | use foo2::bar2;
| ^^^^ maybe a missing crate `foo2`?
+ |
+ = help: consider adding `extern crate foo2` to use the `foo2` crate
error[E0432]: unresolved import `baz2`
--> $DIR/unresolved-imports-used.rs:15:5
|
LL | use baz2::*;
| ^^^^ maybe a missing crate `baz2`?
+ |
+ = help: consider adding `extern crate baz2` to use the `baz2` crate
error[E0603]: function `quz` is private
--> $DIR/unresolved-imports-used.rs:9:10
diff --git a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
index 4c11f354494..c6e6ea1e096 100644
--- a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
+++ b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr
@@ -9,6 +9,7 @@ LL | assert_eq!(a, 0);
|
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might have forgotten to call this function
+ --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
LL | if !(*left_val() == *right_val) {
| ++
diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr b/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr
index 247d6b0ed71..54ee45c2867 100644
--- a/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr
+++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-use.stderr
@@ -14,6 +14,8 @@ error[E0432]: unresolved import `r#extern`
|
LL | use extern::foo;
| ^^^^^^ maybe a missing crate `r#extern`?
+ |
+ = help: consider adding `extern crate r#extern` to use the `r#extern` crate
error: aborting due to 2 previous errors
diff --git a/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr b/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr
index 09978b35f7e..0af58bc61f4 100644
--- a/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr
+++ b/src/test/ui/methods/method-on-ambiguous-numeric-type.stderr
@@ -46,6 +46,7 @@ LL | bar.pow(2);
| ^^^
|
help: you must specify a type for this binding, like `i32`
+ --> $DIR/auxiliary/macro-in-other-crate.rs:3:29
|
LL | ($ident:ident) => { let $ident: i32 = 42; }
| ~~~~~~~~~~~
diff --git a/src/test/ui/privacy/restricted/test.stderr b/src/test/ui/privacy/restricted/test.stderr
index 5a85aef2b17..c81520c35cd 100644
--- a/src/test/ui/privacy/restricted/test.stderr
+++ b/src/test/ui/privacy/restricted/test.stderr
@@ -3,6 +3,8 @@ error[E0433]: failed to resolve: maybe a missing crate `bad`?
|
LL | pub(in bad::path) mod m1 {}
| ^^^ maybe a missing crate `bad`?
+ |
+ = help: consider adding `extern crate bad` to use the `bad` crate
error[E0742]: visibilities can only be restricted to ancestor modules
--> $DIR/test.rs:51:12
diff --git a/src/test/ui/resolve/editions-crate-root-2015.stderr b/src/test/ui/resolve/editions-crate-root-2015.stderr
index f8d65fec3d1..00cdd0c58f4 100644
--- a/src/test/ui/resolve/editions-crate-root-2015.stderr
+++ b/src/test/ui/resolve/editions-crate-root-2015.stderr
@@ -3,12 +3,16 @@ error[E0433]: failed to resolve: maybe a missing crate `nonexistant`?
|
LL | fn global_inner(_: ::nonexistant::Foo) {
| ^^^^^^^^^^^ maybe a missing crate `nonexistant`?
+ |
+ = help: consider adding `extern crate nonexistant` to use the `nonexistant` crate
error[E0433]: failed to resolve: maybe a missing crate `nonexistant`?
--> $DIR/editions-crate-root-2015.rs:7:30
|
LL | fn crate_inner(_: crate::nonexistant::Foo) {
| ^^^^^^^^^^^ maybe a missing crate `nonexistant`?
+ |
+ = help: consider adding `extern crate nonexistant` to use the `nonexistant` crate
error[E0412]: cannot find type `nonexistant` in the crate root
--> $DIR/editions-crate-root-2015.rs:11:25
diff --git a/src/test/ui/resolve/extern-prelude-fail.stderr b/src/test/ui/resolve/extern-prelude-fail.stderr
index a59f4c952bb..a1591914b4d 100644
--- a/src/test/ui/resolve/extern-prelude-fail.stderr
+++ b/src/test/ui/resolve/extern-prelude-fail.stderr
@@ -3,12 +3,16 @@ error[E0432]: unresolved import `extern_prelude`
|
LL | use extern_prelude::S;
| ^^^^^^^^^^^^^^ maybe a missing crate `extern_prelude`?
+ |
+ = help: consider adding `extern crate extern_prelude` to use the `extern_prelude` crate
error[E0433]: failed to resolve: maybe a missing crate `extern_prelude`?
--> $DIR/extern-prelude-fail.rs:8:15
|
LL | let s = ::extern_prelude::S;
| ^^^^^^^^^^^^^^ maybe a missing crate `extern_prelude`?
+ |
+ = help: consider adding `extern crate extern_prelude` to use the `extern_prelude` crate
error: aborting due to 2 previous errors
diff --git a/src/test/ui/resolve/issue-82865.stderr b/src/test/ui/resolve/issue-82865.stderr
index 7898c2a360f..730fd6d6026 100644
--- a/src/test/ui/resolve/issue-82865.stderr
+++ b/src/test/ui/resolve/issue-82865.stderr
@@ -3,6 +3,8 @@ error[E0433]: failed to resolve: maybe a missing crate `x`?
|
LL | use x::y::z;
| ^ maybe a missing crate `x`?
+ |
+ = help: consider adding `extern crate x` to use the `x` crate
error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope
--> $DIR/issue-82865.rs:8:10
diff --git a/src/test/ui/resolve/resolve-bad-visibility.stderr b/src/test/ui/resolve/resolve-bad-visibility.stderr
index 197ecf0cb00..2ac41b87562 100644
--- a/src/test/ui/resolve/resolve-bad-visibility.stderr
+++ b/src/test/ui/resolve/resolve-bad-visibility.stderr
@@ -21,12 +21,16 @@ error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
|
LL | pub(in nonexistent) struct G;
| ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
+ |
+ = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate
error[E0433]: failed to resolve: maybe a missing crate `too_soon`?
--> $DIR/resolve-bad-visibility.rs:8:8
|
LL | pub(in too_soon) struct H;
| ^^^^^^^^ maybe a missing crate `too_soon`?
+ |
+ = help: consider adding `extern crate too_soon` to use the `too_soon` crate
error: aborting due to 5 previous errors
diff --git a/src/test/ui/simd/portable-intrinsics-arent-exposed.stderr b/src/test/ui/simd/portable-intrinsics-arent-exposed.stderr
index f568aa04295..870f4064de4 100644
--- a/src/test/ui/simd/portable-intrinsics-arent-exposed.stderr
+++ b/src/test/ui/simd/portable-intrinsics-arent-exposed.stderr
@@ -3,6 +3,8 @@ error[E0433]: failed to resolve: maybe a missing crate `core`?
|
LL | use core::simd::intrinsics;
| ^^^^ maybe a missing crate `core`?
+ |
+ = help: consider adding `extern crate core` to use the `core` crate
error[E0432]: unresolved import `std::simd::intrinsics`
--> $DIR/portable-intrinsics-arent-exposed.rs:5:5
diff --git a/src/test/ui/suggestions/enum-method-probe.fixed b/src/test/ui/suggestions/enum-method-probe.fixed
new file mode 100644
index 00000000000..6499c92bc6f
--- /dev/null
+++ b/src/test/ui/suggestions/enum-method-probe.fixed
@@ -0,0 +1,59 @@
+// compile-flags: --edition=2021
+// run-rustfix
+
+#![allow(unused)]
+
+struct Foo;
+
+impl Foo {
+ fn get(&self) -> u8 {
+ 42
+ }
+}
+
+fn test_result_in_result() -> Result<(), ()> {
+ let res: Result<_, ()> = Ok(Foo);
+ res?.get();
+ //~^ ERROR no method named `get` found for enum `Result` in the current scope
+ //~| HELP use the `?` operator
+ Ok(())
+}
+
+async fn async_test_result_in_result() -> Result<(), ()> {
+ let res: Result<_, ()> = Ok(Foo);
+ res?.get();
+ //~^ ERROR no method named `get` found for enum `Result` in the current scope
+ //~| HELP use the `?` operator
+ Ok(())
+}
+
+fn test_result_in_unit_return() {
+ let res: Result<_, ()> = Ok(Foo);
+ res.expect("REASON").get();
+ //~^ ERROR no method named `get` found for enum `Result` in the current scope
+ //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
+}
+
+async fn async_test_result_in_unit_return() {
+ let res: Result<_, ()> = Ok(Foo);
+ res.expect("REASON").get();
+ //~^ ERROR no method named `get` found for enum `Result` in the current scope
+ //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
+}
+
+fn test_option_in_option() -> Option<()> {
+ let res: Option<_> = Some(Foo);
+ res?.get();
+ //~^ ERROR no method named `get` found for enum `Option` in the current scope
+ //~| HELP use the `?` operator
+ Some(())
+}
+
+fn test_option_in_unit_return() {
+ let res: Option<_> = Some(Foo);
+ res.expect("REASON").get();
+ //~^ ERROR no method named `get` found for enum `Option` in the current scope
+ //~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None`
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/enum-method-probe.rs b/src/test/ui/suggestions/enum-method-probe.rs
new file mode 100644
index 00000000000..18ea8ed8a58
--- /dev/null
+++ b/src/test/ui/suggestions/enum-method-probe.rs
@@ -0,0 +1,59 @@
+// compile-flags: --edition=2021
+// run-rustfix
+
+#![allow(unused)]
+
+struct Foo;
+
+impl Foo {
+ fn get(&self) -> u8 {
+ 42
+ }
+}
+
+fn test_result_in_result() -> Result<(), ()> {
+ let res: Result<_, ()> = Ok(Foo);
+ res.get();
+ //~^ ERROR no method named `get` found for enum `Result` in the current scope
+ //~| HELP use the `?` operator
+ Ok(())
+}
+
+async fn async_test_result_in_result() -> Result<(), ()> {
+ let res: Result<_, ()> = Ok(Foo);
+ res.get();
+ //~^ ERROR no method named `get` found for enum `Result` in the current scope
+ //~| HELP use the `?` operator
+ Ok(())
+}
+
+fn test_result_in_unit_return() {
+ let res: Result<_, ()> = Ok(Foo);
+ res.get();
+ //~^ ERROR no method named `get` found for enum `Result` in the current scope
+ //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
+}
+
+async fn async_test_result_in_unit_return() {
+ let res: Result<_, ()> = Ok(Foo);
+ res.get();
+ //~^ ERROR no method named `get` found for enum `Result` in the current scope
+ //~| HELP consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
+}
+
+fn test_option_in_option() -> Option<()> {
+ let res: Option<_> = Some(Foo);
+ res.get();
+ //~^ ERROR no method named `get` found for enum `Option` in the current scope
+ //~| HELP use the `?` operator
+ Some(())
+}
+
+fn test_option_in_unit_return() {
+ let res: Option<_> = Some(Foo);
+ res.get();
+ //~^ ERROR no method named `get` found for enum `Option` in the current scope
+ //~| HELP consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None`
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/enum-method-probe.stderr b/src/test/ui/suggestions/enum-method-probe.stderr
new file mode 100644
index 00000000000..6ed14984f47
--- /dev/null
+++ b/src/test/ui/suggestions/enum-method-probe.stderr
@@ -0,0 +1,99 @@
+error[E0599]: no method named `get` found for enum `Result` in the current scope
+ --> $DIR/enum-method-probe.rs:24:9
+ |
+LL | res.get();
+ | ^^^ method not found in `Result<Foo, ()>`
+ |
+note: the method `get` exists on the type `Foo`
+ --> $DIR/enum-method-probe.rs:9:5
+ |
+LL | fn get(&self) -> u8 {
+ | ^^^^^^^^^^^^^^^^^^^
+help: use the `?` operator to extract the `Foo` value, propagating a `Result::Err` value to the caller
+ |
+LL | res?.get();
+ | +
+
+error[E0599]: no method named `get` found for enum `Result` in the current scope
+ --> $DIR/enum-method-probe.rs:39:9
+ |
+LL | res.get();
+ | ^^^ method not found in `Result<Foo, ()>`
+ |
+note: the method `get` exists on the type `Foo`
+ --> $DIR/enum-method-probe.rs:9:5
+ |
+LL | fn get(&self) -> u8 {
+ | ^^^^^^^^^^^^^^^^^^^
+help: consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
+ |
+LL | res.expect("REASON").get();
+ | +++++++++++++++++
+
+error[E0599]: no method named `get` found for enum `Result` in the current scope
+ --> $DIR/enum-method-probe.rs:16:9
+ |
+LL | res.get();
+ | ^^^ method not found in `Result<Foo, ()>`
+ |
+note: the method `get` exists on the type `Foo`
+ --> $DIR/enum-method-probe.rs:9:5
+ |
+LL | fn get(&self) -> u8 {
+ | ^^^^^^^^^^^^^^^^^^^
+help: use the `?` operator to extract the `Foo` value, propagating a `Result::Err` value to the caller
+ |
+LL | res?.get();
+ | +
+
+error[E0599]: no method named `get` found for enum `Result` in the current scope
+ --> $DIR/enum-method-probe.rs:32:9
+ |
+LL | res.get();
+ | ^^^ method not found in `Result<Foo, ()>`
+ |
+note: the method `get` exists on the type `Foo`
+ --> $DIR/enum-method-probe.rs:9:5
+ |
+LL | fn get(&self) -> u8 {
+ | ^^^^^^^^^^^^^^^^^^^
+help: consider using `Result::expect` to unwrap the `Foo` value, panicking if the value is a `Result::Err`
+ |
+LL | res.expect("REASON").get();
+ | +++++++++++++++++
+
+error[E0599]: no method named `get` found for enum `Option` in the current scope
+ --> $DIR/enum-method-probe.rs:46:9
+ |
+LL | res.get();
+ | ^^^ method not found in `Option<Foo>`
+ |
+note: the method `get` exists on the type `Foo`
+ --> $DIR/enum-method-probe.rs:9:5
+ |
+LL | fn get(&self) -> u8 {
+ | ^^^^^^^^^^^^^^^^^^^
+help: use the `?` operator to extract the `Foo` value, propagating an `Option::None` value to the caller
+ |
+LL | res?.get();
+ | +
+
+error[E0599]: no method named `get` found for enum `Option` in the current scope
+ --> $DIR/enum-method-probe.rs:54:9
+ |
+LL | res.get();
+ | ^^^ method not found in `Option<Foo>`
+ |
+note: the method `get` exists on the type `Foo`
+ --> $DIR/enum-method-probe.rs:9:5
+ |
+LL | fn get(&self) -> u8 {
+ | ^^^^^^^^^^^^^^^^^^^
+help: consider using `Option::expect` to unwrap the `Foo` value, panicking if the value is an `Option::None`
+ |
+LL | res.expect("REASON").get();
+ | +++++++++++++++++
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/unresolved/unresolved-asterisk-imports.stderr b/src/test/ui/unresolved/unresolved-asterisk-imports.stderr
index a789179db65..8df8eab34a7 100644
--- a/src/test/ui/unresolved/unresolved-asterisk-imports.stderr
+++ b/src/test/ui/unresolved/unresolved-asterisk-imports.stderr
@@ -3,6 +3,8 @@ error[E0432]: unresolved import `not_existing_crate`
|
LL | use not_existing_crate::*;
| ^^^^^^^^^^^^^^^^^^ maybe a missing crate `not_existing_crate`?
+ |
+ = help: consider adding `extern crate not_existing_crate` to use the `not_existing_crate` crate
error: aborting due to previous error
diff --git a/src/test/ui/unresolved/unresolved-import.rs b/src/test/ui/unresolved/unresolved-import.rs
index b65c3dfb90b..4125c593c74 100644
--- a/src/test/ui/unresolved/unresolved-import.rs
+++ b/src/test/ui/unresolved/unresolved-import.rs
@@ -1,5 +1,6 @@
use foo::bar; //~ ERROR unresolved import `foo` [E0432]
//~^ maybe a missing crate `foo`?
+ //~| HELP consider adding `extern crate foo` to use the `foo` crate
use bar::Baz as x; //~ ERROR unresolved import `bar::Baz` [E0432]
//~| no `Baz` in `bar`
diff --git a/src/test/ui/unresolved/unresolved-import.stderr b/src/test/ui/unresolved/unresolved-import.stderr
index d4bfea57809..0dd928c8b6f 100644
--- a/src/test/ui/unresolved/unresolved-import.stderr
+++ b/src/test/ui/unresolved/unresolved-import.stderr
@@ -3,9 +3,11 @@ error[E0432]: unresolved import `foo`
|
LL | use foo::bar;
| ^^^ maybe a missing crate `foo`?
+ |
+ = help: consider adding `extern crate foo` to use the `foo` crate
error[E0432]: unresolved import `bar::Baz`
- --> $DIR/unresolved-import.rs:4:5
+ --> $DIR/unresolved-import.rs:5:5
|
LL | use bar::Baz as x;
| ^^^^^---^^^^^
@@ -14,7 +16,7 @@ LL | use bar::Baz as x;
| no `Baz` in `bar`
error[E0432]: unresolved import `food::baz`
- --> $DIR/unresolved-import.rs:9:5
+ --> $DIR/unresolved-import.rs:10:5
|
LL | use food::baz;
| ^^^^^^---
@@ -23,7 +25,7 @@ LL | use food::baz;
| no `baz` in `food`
error[E0432]: unresolved import `food::beens`
- --> $DIR/unresolved-import.rs:14:12
+ --> $DIR/unresolved-import.rs:15:12
|
LL | use food::{beens as Foo};
| -----^^^^^^^
@@ -32,13 +34,13 @@ LL | use food::{beens as Foo};
| help: a similar name exists in the module: `beans`
error[E0432]: unresolved import `MyEnum`
- --> $DIR/unresolved-import.rs:38:9
+ --> $DIR/unresolved-import.rs:39:9
|
LL | use MyEnum::*;
| ^^^^^^ help: a similar path exists: `self::MyEnum`
error[E0432]: unresolved import `Enum`
- --> $DIR/unresolved-import.rs:48:9
+ --> $DIR/unresolved-import.rs:49:9
|
LL | use Enum::*;
| ^^^^ help: a similar path exists: `self::Enum`
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 39ad1039d9e3e1746177bf5d134af4c164f9552
+Subproject 38472bc19f2f76e245eba54a6e97ee6821b3c1d
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 283b20fc24d..b1c82ac76e8 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -125,7 +125,7 @@ fn check_rvalue<'tcx>(
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
check_place(tcx, *place, span, body)
},
- Rvalue::Cast(CastKind::PointerAddress, _, _) => {
+ Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
Err((span, "casting pointers to ints is unstable in const fn".into()))
},
Rvalue::Cast(CastKind::Misc, operand, _) => {
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 065ff89e33b67b3527fcdd56cf8b432e593e32d
+Subproject 749efd29565a9b8f47afb441aaacfcc10bc145d