diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs
index a75e7409fba18..25cd960dbf1d0 100644
--- a/compiler/rustc_attr/src/session_diagnostics.rs
+++ b/compiler/rustc_attr/src/session_diagnostics.rs
@@ -223,14 +223,12 @@ impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral {
error_code!(E0565),
);
if self.is_bytestr {
- if let Ok(lint_str) = sess.source_map().span_to_snippet(self.span) {
- diag.span_suggestion(
- self.span,
- fluent::attr::unsupported_literal_suggestion,
- &lint_str[1..],
- Applicability::MaybeIncorrect,
- );
- }
+ diag.span_suggestion(
+ sess.source_map().start_point(self.span),
+ fluent::attr::unsupported_literal_suggestion,
+ "",
+ Applicability::MaybeIncorrect,
+ );
}
diag
}
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 56721cc3f5c75..dd9590016b990 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -1,5 +1,8 @@
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{
+ Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed,
+};
use rustc_hir as hir;
+use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
use rustc_middle::hir::map::Map;
use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
@@ -614,7 +617,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
"trait `IndexMut` is required to modify indexed content, \
but it is not implemented for `{ty}`",
));
- self.suggest_map_index_mut_alternatives(ty, &mut err);
+ self.suggest_map_index_mut_alternatives(ty, &mut err, span);
}
_ => (),
}
@@ -632,13 +635,120 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
&self,
ty: Ty<'_>,
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
+ span: Span,
) {
let Some(adt) = ty.ty_adt_def() else { return };
let did = adt.did();
if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did)
|| self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did)
{
- err.help(format!("to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API"));
+ struct V<'a, 'b, 'tcx, G: EmissionGuarantee> {
+ assign_span: Span,
+ err: &'a mut DiagnosticBuilder<'b, G>,
+ ty: Ty<'tcx>,
+ suggested: bool,
+ }
+ impl<'a, 'b: 'a, 'hir, 'tcx, G: EmissionGuarantee> Visitor<'hir> for V<'a, 'b, 'tcx, G> {
+ fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'hir>) {
+ hir::intravisit::walk_stmt(self, stmt);
+ let expr = match stmt.kind {
+ hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr,
+ hir::StmtKind::Local(hir::Local { init: Some(expr), .. }) => expr,
+ _ => {
+ return;
+ }
+ };
+ if let hir::ExprKind::Assign(place, rv, _sp) = expr.kind
+ && let hir::ExprKind::Index(val, index) = place.kind
+ && (expr.span == self.assign_span || place.span == self.assign_span)
+ {
+ // val[index] = rv;
+ // ---------- place
+ self.err.multipart_suggestions(
+ &format!(
+ "to modify a `{}`, use `.get_mut()`, `.insert()` or the entry API",
+ self.ty,
+ ),
+ vec![
+ vec![ // val.insert(index, rv);
+ (
+ val.span.shrink_to_hi().with_hi(index.span.lo()),
+ ".insert(".to_string(),
+ ),
+ (
+ index.span.shrink_to_hi().with_hi(rv.span.lo()),
+ ", ".to_string(),
+ ),
+ (rv.span.shrink_to_hi(), ")".to_string()),
+ ],
+ vec![ // val.get_mut(index).map(|v| { *v = rv; });
+ (
+ val.span.shrink_to_hi().with_hi(index.span.lo()),
+ ".get_mut(".to_string(),
+ ),
+ (
+ index.span.shrink_to_hi().with_hi(place.span.hi()),
+ ").map(|val| { *val".to_string(),
+ ),
+ (
+ rv.span.shrink_to_hi(),
+ "; })".to_string(),
+ ),
+ ],
+ vec![ // let x = val.entry(index).or_insert(rv);
+ (val.span.shrink_to_lo(), "let val = ".to_string()),
+ (
+ val.span.shrink_to_hi().with_hi(index.span.lo()),
+ ".entry(".to_string(),
+ ),
+ (
+ index.span.shrink_to_hi().with_hi(rv.span.lo()),
+ ").or_insert(".to_string(),
+ ),
+ (rv.span.shrink_to_hi(), ")".to_string()),
+ ],
+ ].into_iter(),
+ Applicability::MachineApplicable,
+ );
+ self.suggested = true;
+ } else if let hir::ExprKind::MethodCall(_path, args @ [_, ..], sp) = expr.kind
+ && let hir::ExprKind::Index(val, index) = args[0].kind
+ && expr.span == self.assign_span
+ {
+ // val[index].path(args..);
+ self.err.multipart_suggestion(
+ &format!("to modify a `{}` use `.get_mut()`", self.ty),
+ vec![
+ (
+ val.span.shrink_to_hi().with_hi(index.span.lo()),
+ ".get_mut(".to_string(),
+ ),
+ (
+ index.span.shrink_to_hi().with_hi(args[0].span.hi()),
+ ").map(|val| val".to_string(),
+ ),
+ (sp.shrink_to_hi(), ")".to_string()),
+ ],
+ Applicability::MachineApplicable,
+ );
+ self.suggested = true;
+ }
+ }
+ }
+ let hir_map = self.infcx.tcx.hir();
+ let def_id = self.body.source.def_id();
+ let hir_id = hir_map.local_def_id_to_hir_id(def_id.as_local().unwrap());
+ let node = hir_map.find(hir_id);
+ let Some(hir::Node::Item(item)) = node else { return; };
+ let hir::ItemKind::Fn(.., body_id) = item.kind else { return; };
+ let body = self.infcx.tcx.hir().body(body_id);
+ let mut v = V { assign_span: span, err, ty, suggested: false };
+ v.visit_body(body);
+ if !v.suggested {
+ err.help(&format!(
+ "to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API",
+ ));
+ }
}
}
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 25a989bdf0525..d0a6f216858b6 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -1500,24 +1500,18 @@ fn vcall_visibility_metadata<'ll, 'tcx>(
// If there is not LTO and the visibility in public, we have to assume that the vtable can
// be seen from anywhere. With multiple CGUs, the vtable is quasi-public.
(Lto::No | Lto::ThinLocal, Visibility::Public, _)
- | (Lto::No, Visibility::Restricted(_) | Visibility::Invisible, false) => {
- VCallVisibility::Public
- }
+ | (Lto::No, Visibility::Restricted(_), false) => VCallVisibility::Public,
// With LTO and a quasi-public visibility, the usages of the functions of the vtable are
// all known by the `LinkageUnit`.
// FIXME: LLVM only supports this optimization for `Lto::Fat` currently. Once it also
// supports `Lto::Thin` the `VCallVisibility` may have to be adjusted for those.
(Lto::Fat | Lto::Thin, Visibility::Public, _)
- | (
- Lto::ThinLocal | Lto::Thin | Lto::Fat,
- Visibility::Restricted(_) | Visibility::Invisible,
- false,
- ) => VCallVisibility::LinkageUnit,
+ | (Lto::ThinLocal | Lto::Thin | Lto::Fat, Visibility::Restricted(_), false) => {
+ VCallVisibility::LinkageUnit
+ }
// If there is only one CGU, private vtables can only be seen by that CGU/translation unit
// and therefore we know of all usages of functions in the vtable.
- (_, Visibility::Restricted(_) | Visibility::Invisible, true) => {
- VCallVisibility::TranslationUnit
- }
+ (_, Visibility::Restricted(_), true) => VCallVisibility::TranslationUnit,
};
let trait_ref_typeid = typeid_for_trait_ref(cx.tcx, trait_ref);
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index e13ad1c95bd04..4601914c25f88 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -74,7 +74,9 @@ fn eval_body_using_ecx<'mir, 'tcx>(
None => InternKind::Constant,
}
};
+ ecx.machine.check_alignment = false; // interning doesn't need to respect alignment
intern_const_alloc_recursive(ecx, intern_kind, &ret)?;
+ // we leave alignment checks off, since this `ecx` will not be used for further evaluation anyway
debug!("eval_body_using_ecx done: {:?}", *ret);
Ok(ret)
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 2a460c74b3d82..6c1e61fccca19 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -89,10 +89,10 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
/// exhaustion error.
///
/// Setting this to `0` disables the limit and allows the interpreter to run forever.
- pub steps_remaining: usize,
+ pub(super) steps_remaining: usize,
/// The virtual call stack.
- pub(crate) stack: Vec>,
+ pub(super) stack: Vec>,
/// We need to make sure consts never point to anything mutable, even recursively. That is
/// relied on for pattern matching on consts with references.
@@ -103,7 +103,7 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
pub(super) can_access_statics: bool,
/// Whether to check alignment during evaluation.
- check_alignment: bool,
+ pub(super) check_alignment: bool,
}
impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 7a9ad44d1d9ae..d182929c40066 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -293,7 +293,7 @@ fn skip_stability_check_due_to_privacy(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
// These are not visible outside crate; therefore
// stability markers are irrelevant, if even present.
- ty::Visibility::Restricted(..) | ty::Visibility::Invisible => true,
+ ty::Visibility::Restricted(..) => true,
}
}
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 3d22f5a04a2bf..aaa66deb2a3ec 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -169,14 +169,10 @@ impl<'tcx> FieldDef {
param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest<'tcx> {
let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env);
- // FIXME(canndrew): Currently enum fields are (incorrectly) stored with
- // `Visibility::Invisible` so we need to override `self.vis` if we're
- // dealing with an enum.
if is_enum {
data_uninhabitedness()
} else {
match self.vis {
- Visibility::Invisible => DefIdForest::empty(),
Visibility::Restricted(from) => {
let forest = DefIdForest::from_id(from);
let iter = Some(forest).into_iter().chain(Some(data_uninhabitedness()));
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index a7833ab64310f..ed04e7660339e 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -268,8 +268,6 @@ pub enum Visibility {
Public,
/// Visible only in the given crate-local module.
Restricted(DefId),
- /// Not visible anywhere in the local crate. This is the visibility of private external items.
- Invisible,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
@@ -366,8 +364,6 @@ impl Visibility {
let restriction = match self {
// Public items are visible everywhere.
Visibility::Public => return true,
- // Private items from other crates are visible nowhere.
- Visibility::Invisible => return false,
// Restricted items are visible in an arbitrary local module.
Visibility::Restricted(other) if other.krate != module.krate => return false,
Visibility::Restricted(module) => module,
@@ -380,7 +376,6 @@ impl Visibility {
pub fn is_at_least(self, vis: Visibility, tree: T) -> bool {
let vis_restriction = match vis {
Visibility::Public => return self == Visibility::Public,
- Visibility::Invisible => return true,
Visibility::Restricted(module) => module,
};
@@ -392,7 +387,6 @@ impl Visibility {
match self {
Visibility::Public => true,
Visibility::Restricted(def_id) => def_id.is_local(),
- Visibility::Invisible => false,
}
}
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 27fa402edcec8..5d562f18a8158 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1731,7 +1731,6 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
if !vis.is_at_least(self.required_visibility, self.tcx) {
let vis_descr = match vis {
ty::Visibility::Public => "public",
- ty::Visibility::Invisible => "private",
ty::Visibility::Restricted(vis_def_id) => {
if vis_def_id == self.tcx.parent_module(hir_id).to_def_id() {
"private"
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index e955a1798b735..8f3b6009bd6ef 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -380,7 +380,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
has_attributes: !item.attrs.is_empty(),
root_span,
root_id,
- vis: Cell::new(vis),
+ vis: Cell::new(Some(vis)),
used: Cell::new(false),
});
@@ -588,7 +588,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
ast::UseTreeKind::Glob => {
let kind = ImportKind::Glob {
is_prelude: self.r.session.contains_name(&item.attrs, sym::prelude_import),
- max_vis: Cell::new(ty::Visibility::Invisible),
+ max_vis: Cell::new(None),
};
self.r.visibilities.insert(self.r.local_def_id(id), vis);
self.add_import(prefix, kind, use_tree.span, id, item, root_span, item.id, vis);
@@ -650,7 +650,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
true,
// The whole `use` item
item,
- ty::Visibility::Invisible,
+ ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod()),
root_span,
);
}
@@ -885,7 +885,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
root_span: item.span,
span: item.span,
module_path: Vec::new(),
- vis: Cell::new(vis),
+ vis: Cell::new(Some(vis)),
used: Cell::new(used),
});
self.r.potentially_unused_imports.push(import);
@@ -1118,7 +1118,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
root_span: span,
span,
module_path: Vec::new(),
- vis: Cell::new(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())),
+ vis: Cell::new(Some(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()))),
used: Cell::new(false),
})
};
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index f2f6f1d895e32..8b58b32b65649 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -227,7 +227,7 @@ impl Resolver<'_> {
for import in self.potentially_unused_imports.iter() {
match import.kind {
_ if import.used.get()
- || import.vis.get().is_public()
+ || import.expect_vis().is_public()
|| import.span.is_dummy() =>
{
if let ImportKind::MacroUse = import.kind {
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 41a0c76d83a95..23c0ca108d385 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -953,7 +953,10 @@ impl<'a> Resolver<'a> {
// Check if one of single imports can still define the name,
// if it can then our result is not determined and can be invalidated.
for single_import in &resolution.single_imports {
- if !self.is_accessible_from(single_import.vis.get(), parent_scope.module) {
+ let Some(import_vis) = single_import.vis.get() else {
+ continue;
+ };
+ if !self.is_accessible_from(import_vis, parent_scope.module) {
continue;
}
let Some(module) = single_import.imported_module.get() else {
@@ -1018,7 +1021,10 @@ impl<'a> Resolver<'a> {
// Check if one of glob imports can still define the name,
// if it can then our "no resolution" result is not determined and can be invalidated.
for glob_import in module.globs.borrow().iter() {
- if !self.is_accessible_from(glob_import.vis.get(), parent_scope.module) {
+ let Some(import_vis) = glob_import.vis.get() else {
+ continue;
+ };
+ if !self.is_accessible_from(import_vis, parent_scope.module) {
continue;
}
let module = match glob_import.imported_module.get() {
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index e0d57ded5bf24..c2491c6ebdec0 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -52,8 +52,8 @@ pub enum ImportKind<'a> {
},
Glob {
is_prelude: bool,
- max_vis: Cell, // The visibility of the greatest re-export.
- // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
+ max_vis: Cell