Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #108070

Merged
merged 24 commits into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
837c1af
rework min_choice algorithm of member constraints
aliemjay Jan 15, 2023
8df27d0
Remove some superfluous type parameters from layout.rs.
mikebenfield Jan 21, 2023
0d59b8c
Remove redundant test.
cjgillot Jan 21, 2023
cd3649b
Only exclude locals if the place is not indirect.
cjgillot Jan 21, 2023
9a6c04f
Handle discriminants in dataflow-const-prop.
cjgillot Jan 21, 2023
c48756c
Limit creation of tracked place directly.
cjgillot Jan 28, 2023
9af191f
Improve value_analysis API.
cjgillot Jan 29, 2023
67a8c16
Complete for_each_aliasing_place.
cjgillot Jan 30, 2023
df889c9
Rename assign_idx methods.
cjgillot Feb 3, 2023
903ca87
Suggest the correct array length on mismatch
clubby789 Jan 21, 2023
e723e43
Enable #[thread_local] on armv6k-nintendo-3ds
ian-h-chamberlain Feb 12, 2023
09797a4
Typo.
cjgillot Feb 13, 2023
43a5cc3
Separate the lifetime of the session and the arena in the resolver
oli-obk Dec 8, 2022
21f4c07
Remove BoxedResolver
oli-obk Dec 13, 2022
d156638
Inline the expansion query
oli-obk Feb 14, 2023
241c6a4
Simplify expansion logic
oli-obk Feb 14, 2023
dfd0afb
Revert to using `RtlGenRandom`
ChrisDenton Feb 14, 2023
83f10ea
Rollup merge of #105300 - aliemjay:member-lower, r=oli-obk
Dylan-DPC Feb 15, 2023
9800dbe
Rollup merge of #107163 - mikebenfield:parameters-pr, r=TaKO8Ki
Dylan-DPC Feb 15, 2023
a110cf5
Rollup merge of #107173 - clubby789:suggest-array-length, r=compiler-…
Dylan-DPC Feb 15, 2023
c78e3c7
Rollup merge of #107411 - cjgillot:dataflow-discriminant, r=oli-obk
Dylan-DPC Feb 15, 2023
587e3df
Rollup merge of #107968 - ian-h-chamberlain:feature/3ds-enable-thread…
Dylan-DPC Feb 15, 2023
504225c
Rollup merge of #108032 - oli-obk:un📦ing_resolver, r=petrochenkov
Dylan-DPC Feb 15, 2023
ef6de70
Rollup merge of #108060 - ChrisDenton:rtlgenrandom, r=thomcc
Dylan-DPC Feb 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 71 additions & 75 deletions compiler/rustc_abi/src/layout.rs

Large diffs are not rendered by default.

71 changes: 59 additions & 12 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub};
use std::str::FromStr;

use bitflags::bitflags;
use rustc_data_structures::intern::Interned;
#[cfg(feature = "nightly")]
use rustc_data_structures::stable_hasher::StableOrd;
use rustc_index::vec::{Idx, IndexVec};
Expand Down Expand Up @@ -1250,9 +1251,9 @@ impl Abi {

#[derive(PartialEq, Eq, Hash, Clone, Debug)]
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
pub enum Variants<V: Idx> {
pub enum Variants {
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
Single { index: V },
Single { index: VariantIdx },

/// Enum-likes with more than one inhabited variant: each variant comes with
/// a *discriminant* (usually the same as the variant index but the user can
Expand All @@ -1262,15 +1263,15 @@ pub enum Variants<V: Idx> {
/// For enums, the tag is the sole field of the layout.
Multiple {
tag: Scalar,
tag_encoding: TagEncoding<V>,
tag_encoding: TagEncoding,
tag_field: usize,
variants: IndexVec<V, LayoutS<V>>,
variants: IndexVec<VariantIdx, LayoutS>,
},
}

#[derive(PartialEq, Eq, Hash, Clone, Debug)]
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
pub enum TagEncoding<V: Idx> {
pub enum TagEncoding {
/// The tag directly stores the discriminant, but possibly with a smaller layout
/// (so converting the tag to the discriminant can require sign extension).
Direct,
Expand All @@ -1285,7 +1286,11 @@ pub enum TagEncoding<V: Idx> {
/// For example, `Option<(usize, &T)>` is represented such that
/// `None` has a null pointer for the second tuple field, and
/// `Some` is the identity function (with a non-null reference).
Niche { untagged_variant: V, niche_variants: RangeInclusive<V>, niche_start: u128 },
Niche {
untagged_variant: VariantIdx,
niche_variants: RangeInclusive<VariantIdx>,
niche_start: u128,
},
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
Expand Down Expand Up @@ -1372,9 +1377,14 @@ impl Niche {
}
}

rustc_index::newtype_index! {
#[derive(HashStable_Generic)]
pub struct VariantIdx {}
}

#[derive(PartialEq, Eq, Hash, Clone)]
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
pub struct LayoutS<V: Idx> {
pub struct LayoutS {
/// Says where the fields are located within the layout.
pub fields: FieldsShape,

Expand All @@ -1385,7 +1395,7 @@ pub struct LayoutS<V: Idx> {
///
/// To access all fields of this layout, both `fields` and the fields of the active variant
/// must be taken into account.
pub variants: Variants<V>,
pub variants: Variants,

/// The `abi` defines how this data is passed between functions, and it defines
/// value restrictions via `valid_range`.
Expand All @@ -1404,13 +1414,13 @@ pub struct LayoutS<V: Idx> {
pub size: Size,
}

impl<V: Idx> LayoutS<V> {
impl LayoutS {
pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar);
let size = scalar.size(cx);
let align = scalar.align(cx);
LayoutS {
variants: Variants::Single { index: V::new(0) },
variants: Variants::Single { index: VariantIdx::new(0) },
fields: FieldsShape::Primitive,
abi: Abi::Scalar(scalar),
largest_niche,
Expand All @@ -1420,7 +1430,7 @@ impl<V: Idx> LayoutS<V> {
}
}

impl<V: Idx> fmt::Debug for LayoutS<V> {
impl fmt::Debug for LayoutS {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// This is how `Layout` used to print before it become
// `Interned<LayoutS>`. We print it like this to avoid having to update
Expand All @@ -1437,6 +1447,43 @@ impl<V: Idx> fmt::Debug for LayoutS<V> {
}
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
#[rustc_pass_by_value]
pub struct Layout<'a>(pub Interned<'a, LayoutS>);

impl<'a> fmt::Debug for Layout<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// See comment on `<LayoutS as Debug>::fmt` above.
self.0.0.fmt(f)
}
}

impl<'a> Layout<'a> {
pub fn fields(self) -> &'a FieldsShape {
&self.0.0.fields
}

pub fn variants(self) -> &'a Variants {
&self.0.0.variants
}

pub fn abi(self) -> Abi {
self.0.0.abi
}

pub fn largest_niche(self) -> Option<Niche> {
self.0.0.largest_niche
}

pub fn align(self) -> AbiAndPrefAlign {
self.0.0.align
}

pub fn size(self) -> Size {
self.0.0.size
}
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum PointerKind {
/// Shared reference. `frozen` indicates the absence of any `UnsafeCell`.
Expand Down Expand Up @@ -1464,7 +1511,7 @@ pub enum InitKind {
UninitMitigated0x01Fill,
}

impl<V: Idx> LayoutS<V> {
impl LayoutS {
/// Returns `true` if the layout corresponds to an unsized type.
pub fn is_unsized(&self) -> bool {
self.abi.is_unsized()
Expand Down
35 changes: 24 additions & 11 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -746,20 +746,33 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
debug!(?choice_regions, "after ub");

// If we ruled everything out, we're done.
if choice_regions.is_empty() {
return false;
}

// Otherwise, we need to find the minimum remaining choice, if
// any, and take that.
debug!("choice_regions remaining are {:#?}", choice_regions);
let Some(&min_choice) = choice_regions.iter().find(|&r1| {
// At this point we can pick any member of `choice_regions`, but to avoid potential
// non-determinism we will pick the *unique minimum* choice.
//
// Because universal regions are only partially ordered (i.e, not every two regions are
// comparable), we will ignore any region that doesn't compare to all others when picking
// the minimum choice.
// For example, consider `choice_regions = ['static, 'a, 'b, 'c, 'd, 'e]`, where
// `'static: 'a, 'static: 'b, 'a: 'c, 'b: 'c, 'c: 'd, 'c: 'e`.
// `['d, 'e]` are ignored because they do not compare - the same goes for `['a, 'b]`.
let totally_ordered_subset = choice_regions.iter().copied().filter(|&r1| {
choice_regions.iter().all(|&r2| {
self.universal_region_relations.outlives(r2, *r1)
self.universal_region_relations.outlives(r1, r2)
|| self.universal_region_relations.outlives(r2, r1)
})
});
// Now we're left with `['static, 'c]`. Pick `'c` as the minimum!
let Some(min_choice) = totally_ordered_subset.reduce(|r1, r2| {
let r1_outlives_r2 = self.universal_region_relations.outlives(r1, r2);
let r2_outlives_r1 = self.universal_region_relations.outlives(r2, r1);
match (r1_outlives_r2, r2_outlives_r1) {
(true, true) => r1.min(r2),
(true, false) => r2,
(false, true) => r1,
(false, false) => bug!("incomparable regions in total order"),
}
}) else {
debug!("no choice region outlived by all others");
debug!("no unique minimum choice");
return false;
};

Expand Down
65 changes: 65 additions & 0 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::Node;
use rustc_middle::dep_graph::DepContext;
Expand Down Expand Up @@ -1985,6 +1986,70 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
(ty::Bool, ty::Tuple(list)) => if list.len() == 0 {
self.suggest_let_for_letchains(&mut err, &trace.cause, span);
}
(ty::Array(_, _), ty::Array(_, _)) => 'block: {
let hir = self.tcx.hir();
let TypeError::FixedArraySize(sz) = terr else {
break 'block;
};
let tykind = match hir.find_by_def_id(trace.cause.body_id) {
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(_, _, body_id),
..
})) => {
let body = hir.body(*body_id);
struct LetVisitor<'v> {
span: Span,
result: Option<&'v hir::Ty<'v>>,
}
impl<'v> Visitor<'v> for LetVisitor<'v> {
fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) {
if self.result.is_some() {
return;
}
// Find a local statement where the initializer has
// the same span as the error and the type is specified.
if let hir::Stmt {
kind: hir::StmtKind::Local(hir::Local {
init: Some(hir::Expr {
span: init_span,
..
}),
ty: Some(array_ty),
..
}),
..
} = s
&& init_span == &self.span {
self.result = Some(*array_ty);
}
}
}
let mut visitor = LetVisitor {span, result: None};
visitor.visit_body(body);
visitor.result.map(|r| &r.peel_refs().kind)
}
Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Const(ty, _),
..
})) => {
Some(&ty.peel_refs().kind)
}
_ => None
};

if let Some(tykind) = tykind
&& let hir::TyKind::Array(_, length) = tykind
&& let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
&& let Some(span) = self.tcx.hir().opt_span(*hir_id)
{
err.span_suggestion(
span,
"consider specifying the actual array length",
sz.found,
Applicability::MaybeIncorrect,
);
}
}
_ => {}
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pub use crate::passes::BoxedResolver;
use crate::util;

use rustc_ast::token;
Expand Down
86 changes: 3 additions & 83 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str, validate_a
use rustc_passes::{self, hir_stats, layout_test};
use rustc_plugin_impl as plugin;
use rustc_query_impl::{OnDiskCache, Queries as TcxQueries};
use rustc_resolve::{Resolver, ResolverArenas};
use rustc_resolve::Resolver;
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType};
use rustc_session::cstore::{CrateStoreDyn, MetadataLoader, MetadataLoaderDyn, Untracked};
use rustc_session::cstore::{CrateStoreDyn, MetadataLoader, Untracked};
use rustc_session::output::filename_for_input;
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
Expand All @@ -37,9 +37,7 @@ use rustc_trait_selection::traits;
use std::any::Any;
use std::ffi::OsString;
use std::io::{self, BufWriter, Write};
use std::marker::PhantomPinned;
use std::path::{Path, PathBuf};
use std::pin::Pin;
use std::sync::{Arc, LazyLock};
use std::{env, fs, iter};

Expand Down Expand Up @@ -73,84 +71,6 @@ fn count_nodes(krate: &ast::Crate) -> usize {
counter.count
}

pub use boxed_resolver::BoxedResolver;
mod boxed_resolver {
use super::*;

pub struct BoxedResolver(Pin<Box<BoxedResolverInner>>);

struct BoxedResolverInner {
session: Lrc<Session>,
resolver_arenas: Option<ResolverArenas<'static>>,
resolver: Option<Resolver<'static>>,
_pin: PhantomPinned,
}

// Note: Drop order is important to prevent dangling references. Resolver must be dropped first,
// then resolver_arenas and session.
impl Drop for BoxedResolverInner {
fn drop(&mut self) {
self.resolver.take();
self.resolver_arenas.take();
}
}

impl BoxedResolver {
pub(super) fn new(
session: Lrc<Session>,
make_resolver: impl for<'a> FnOnce(&'a Session, &'a ResolverArenas<'a>) -> Resolver<'a>,
) -> BoxedResolver {
let mut boxed_resolver = Box::new(BoxedResolverInner {
session,
resolver_arenas: Some(Resolver::arenas()),
resolver: None,
_pin: PhantomPinned,
});
// SAFETY: `make_resolver` takes a resolver arena with an arbitrary lifetime and
// returns a resolver with the same lifetime as the arena. We ensure that the arena
// outlives the resolver in the drop impl and elsewhere so these transmutes are sound.
unsafe {
let resolver = make_resolver(
std::mem::transmute::<&Session, &Session>(&boxed_resolver.session),
std::mem::transmute::<&ResolverArenas<'_>, &ResolverArenas<'_>>(
boxed_resolver.resolver_arenas.as_ref().unwrap(),
),
);
boxed_resolver.resolver = Some(resolver);
BoxedResolver(Pin::new_unchecked(boxed_resolver))
}
}

pub fn access<F: for<'a> FnOnce(&mut Resolver<'a>) -> R, R>(&mut self, f: F) -> R {
// SAFETY: The resolver doesn't need to be pinned.
let mut resolver = unsafe {
self.0.as_mut().map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
};
f((&mut *resolver).as_mut().unwrap())
}

pub fn into_outputs(mut self) -> ty::ResolverOutputs {
// SAFETY: The resolver doesn't need to be pinned.
let mut resolver = unsafe {
self.0.as_mut().map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
};
resolver.take().unwrap().into_outputs()
}
}
}

pub fn create_resolver(
sess: Lrc<Session>,
metadata_loader: Box<MetadataLoaderDyn>,
krate: &ast::Crate,
crate_name: Symbol,
) -> BoxedResolver {
trace!("create_resolver");
BoxedResolver::new(sess, move |sess, resolver_arenas| {
Resolver::new(sess, krate, crate_name, metadata_loader, resolver_arenas)
})
}

pub fn register_plugins<'a>(
sess: &'a Session,
metadata_loader: &'a dyn MetadataLoader,
Expand Down Expand Up @@ -256,7 +176,7 @@ pub fn configure_and_expand(
lint_store: &LintStore,
mut krate: ast::Crate,
crate_name: Symbol,
resolver: &mut Resolver<'_>,
resolver: &mut Resolver<'_, '_>,
) -> Result<ast::Crate> {
trace!("configure_and_expand");
pre_expansion_lint(sess, lint_store, resolver.registered_tools(), &krate, crate_name);
Expand Down
Loading