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 #95572

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5d30180
Handle rustc_const_stable attribute in library feature collector
dtolnay Mar 27, 2022
4246916
Adjust feature names that disagree on const stabilization version
dtolnay Mar 27, 2022
3c8e7b9
Adjust MaybeUninit feature names to avoid changing unstable one
dtolnay Mar 31, 2022
971ecff
Fix feature name of stable parts of strict_provenance
dtolnay Mar 31, 2022
b657cb5
Add error message suggestion for missing noreturn in naked function
jam1garner Mar 31, 2022
2a82763
Implement provenance preserving method on NonNull
declanvk Apr 1, 2022
1f232b8
Fix `thread_local!` macro to be compatible with `no_implicit_prelude`
niluxv Apr 1, 2022
18fae7b
update comments
lcnr Apr 1, 2022
c2b5a7e
remove `unify_key::replace_if_possible`
lcnr Apr 1, 2022
389c83b
remove unused incorrect `EqUnifyValue` impl
lcnr Apr 1, 2022
af24588
invalid_value lint: detect invalid initialization of arrays
RalfJung Mar 27, 2022
d3fe28b
Make GATs object safe under generic_associated_types_extended feature
jackh726 Mar 13, 2022
f793b69
Reword purpose description of noreturn in naked function
jam1garner Apr 1, 2022
bd70a56
Rollup merge of #94911 - jackh726:gats_extended_2, r=compiler-errors
matthiaskrgr Apr 1, 2022
41a7251
Rollup merge of #95354 - dtolnay:rustc_const_stable, r=lcnr
matthiaskrgr Apr 1, 2022
67f9ce4
Rollup merge of #95373 - RalfJung:invalid_value, r=davidtwco
matthiaskrgr Apr 1, 2022
116f8bd
Rollup merge of #95544 - jam1garner:improve-naked-noreturn-diagnostic…
matthiaskrgr Apr 1, 2022
388bff8
Rollup merge of #95556 - declanvk:nonnull-provenance, r=dtolnay
matthiaskrgr Apr 1, 2022
ebd42a8
Rollup merge of #95557 - niluxv:issue-95533, r=dtolnay
matthiaskrgr Apr 1, 2022
b0cc70b
Rollup merge of #95559 - lcnr:inferctxt-typeck, r=oli-obk
matthiaskrgr Apr 1, 2022
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
1 change: 0 additions & 1 deletion compiler/rustc_infer/src/infer/canonical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
/// At the end of processing, the substitution S (once
/// canonicalized) then represents the values that you computed
/// for each of the canonical inputs to your query.

pub fn instantiate_canonical_with_fresh_inference_vars<T>(
&self,
span: Span,
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,12 @@ use super::glb::Glb;
use super::lub::Lub;
use super::sub::Sub;
use super::type_variable::TypeVariableValue;
use super::unify_key::replace_if_possible;
use super::unify_key::{ConstVarValue, ConstVariableValue};
use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use super::{InferCtxt, MiscVariable, TypeTrace};

use crate::traits::{Obligation, PredicateObligations};

use rustc_data_structures::sso::SsoHashMap;
use rustc_hir::def_id::DefId;
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
Expand Down Expand Up @@ -140,8 +137,8 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
return Ok(a);
}

let a = replace_if_possible(&mut self.inner.borrow_mut().const_unification_table(), a);
let b = replace_if_possible(&mut self.inner.borrow_mut().const_unification_table(), b);
let a = self.shallow_resolve(a);
let b = self.shallow_resolve(b);

let a_is_expected = relation.a_is_expected();

Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_infer/src/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,13 @@
//! solving a set of constraints. In contrast, the type inferencer assigns a value to each type
//! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type
//! inferencer knows "so far".

use super::InferCtxt;
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::infer::unify_key::ToType;
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};

use rustc_data_structures::fx::FxHashMap;

use std::collections::hash_map::Entry;

use super::unify_key::ToType;
use super::InferCtxt;

pub struct TypeFreshener<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,
ty_freshen_count: u32,
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ mod sub;
pub mod type_variable;
mod undo_log;

pub use rustc_middle::infer::unify_key;

#[must_use]
#[derive(Debug)]
pub struct InferOk<'tcx, T> {
Expand Down Expand Up @@ -558,9 +556,9 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
}
}

/// Helper type of a temporary returned by `tcx.infer_ctxt()`.
/// Necessary because we can't write the following bound:
/// `F: for<'b, 'tcx> where 'tcx FnOnce(InferCtxt<'b, 'tcx>)`.
/// A temporary returned by `tcx.infer_ctxt()`. This is necessary
/// for multiple `InferCtxt` to share the same `in_progress_typeck_results`
/// without using `Rc` or something similar.
pub struct InferCtxtBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
Expand Down
23 changes: 16 additions & 7 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2548,7 +2548,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
/// Return `Some` only if we are sure this type does *not*
/// allow zero initialization.
fn ty_find_init_error<'tcx>(
tcx: TyCtxt<'tcx>,
cx: &LateContext<'tcx>,
ty: Ty<'tcx>,
init: InitKind,
) -> Option<InitError> {
Expand All @@ -2575,7 +2575,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
Adt(adt_def, substs) if !adt_def.is_union() => {
// First check if this ADT has a layout attribute (like `NonNull` and friends).
use std::ops::Bound;
match tcx.layout_scalar_valid_range(adt_def.did()) {
match cx.tcx.layout_scalar_valid_range(adt_def.did()) {
// We exploit here that `layout_scalar_valid_range` will never
// return `Bound::Excluded`. (And we have tests checking that we
// handle the attribute correctly.)
Expand Down Expand Up @@ -2603,12 +2603,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
// Proceed recursively, check all fields.
let variant = &adt_def.variant(VariantIdx::from_u32(0));
variant.fields.iter().find_map(|field| {
ty_find_init_error(tcx, field.ty(tcx, substs), init).map(
ty_find_init_error(cx, field.ty(cx.tcx, substs), init).map(
|(mut msg, span)| {
if span.is_none() {
// Point to this field, should be helpful for figuring
// out where the source of the error is.
let span = tcx.def_span(field.did);
let span = cx.tcx.def_span(field.did);
write!(
&mut msg,
" (in this {} field)",
Expand All @@ -2627,7 +2627,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
// Multi-variant enum.
_ => {
if init == InitKind::Uninit && is_multi_variant(*adt_def) {
let span = tcx.def_span(adt_def.did());
let span = cx.tcx.def_span(adt_def.did());
Some((
"enums have to be initialized to a variant".to_string(),
Some(span),
Expand All @@ -2642,7 +2642,16 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
}
Tuple(..) => {
// Proceed recursively, check all fields.
ty.tuple_fields().iter().find_map(|field| ty_find_init_error(tcx, field, init))
ty.tuple_fields().iter().find_map(|field| ty_find_init_error(cx, field, init))
}
Array(ty, len) => {
if matches!(len.try_eval_usize(cx.tcx, cx.param_env), Some(v) if v > 0) {
// Array length known at array non-empty -- recurse.
ty_find_init_error(cx, *ty, init)
} else {
// Empty array or size unknown.
None
}
}
// Conservative fallback.
_ => None,
Expand All @@ -2655,7 +2664,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
// We are extremely conservative with what we warn about.
let conjured_ty = cx.typeck_results().expr_ty(expr);
if let Some((msg, span)) =
with_no_trimmed_paths!(ty_find_init_error(cx.tcx, conjured_ty, init))
with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init))
{
cx.struct_span_lint(INVALID_VALUE, expr.span, |lint| {
let mut err = lint.build(&format!(
Expand Down
29 changes: 2 additions & 27 deletions compiler/rustc_middle/src/infer/unify_key.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
use crate::ty::{self, InferConst, Ty, TyCtxt};
use rustc_data_structures::snapshot_vec;
use rustc_data_structures::undo_log::UndoLogs;
use rustc_data_structures::unify::{
self, EqUnifyValue, InPlace, NoError, UnificationTable, UnifyKey, UnifyValue,
};
use crate::ty::{self, Ty, TyCtxt};
use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue};
use rustc_span::def_id::DefId;
use rustc_span::symbol::Symbol;
use rustc_span::Span;

use std::cmp;
use std::marker::PhantomData;

Expand Down Expand Up @@ -165,23 +160,3 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
})
}
}

impl<'tcx> EqUnifyValue for ty::Const<'tcx> {}

pub fn replace_if_possible<'tcx, V, L>(
table: &mut UnificationTable<InPlace<ty::ConstVid<'tcx>, V, L>>,
c: ty::Const<'tcx>,
) -> ty::Const<'tcx>
where
V: snapshot_vec::VecLike<unify::Delegate<ty::ConstVid<'tcx>>>,
L: UndoLogs<snapshot_vec::UndoLog<unify::Delegate<ty::ConstVid<'tcx>>>>,
{
if let ty::ConstKind::Infer(InferConst::Var(vid)) = c.val() {
match table.probe_value(vid).val.known() {
Some(c) => c,
None => c,
}
} else {
c
}
}
11 changes: 7 additions & 4 deletions compiler/rustc_passes/src/lib_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ impl<'tcx> LibFeatureCollector<'tcx> {
}

fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option<Symbol>, Span)> {
let stab_attrs = [sym::stable, sym::unstable, sym::rustc_const_unstable];
let stab_attrs =
[sym::stable, sym::unstable, sym::rustc_const_stable, sym::rustc_const_unstable];

// Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`,
// `#[rustc_const_unstable (..)]`).
// Find a stability attribute: one of #[stable(…)], #[unstable(…)],
// #[rustc_const_stable(…)], or #[rustc_const_unstable(…)].
if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.has_name(**stab_attr)) {
let meta_kind = attr.meta_kind();
if let Some(MetaItemKind::List(ref metas)) = meta_kind {
Expand All @@ -52,7 +53,9 @@ impl<'tcx> LibFeatureCollector<'tcx> {
// This additional check for stability is to make sure we
// don't emit additional, irrelevant errors for malformed
// attributes.
if *stab_attr != sym::stable || since.is_some() {
let is_unstable =
matches!(*stab_attr, sym::unstable | sym::rustc_const_unstable);
if since.is_some() || is_unstable {
return Some((feature, since, attr.span));
}
}
Expand Down
15 changes: 14 additions & 1 deletion compiler/rustc_passes/src/naked_functions.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Checks validity of naked functions.

use rustc_ast::{Attribute, InlineAsmOptions};
use rustc_errors::struct_span_err;
use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{FnKind, Visitor};
Expand Down Expand Up @@ -274,12 +274,25 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
}

if !asm.options.contains(InlineAsmOptions::NORETURN) {
let last_span = asm
.operands
.last()
.map_or_else(|| asm.template_strs.last().unwrap().2, |op| op.1)
.shrink_to_hi();

struct_span_err!(
self.tcx.sess,
span,
E0787,
"asm in naked functions must use `noreturn` option"
)
.span_suggestion(
last_span,
"consider specifying that the asm block is responsible \
for returning from the function",
String::from(", options(noreturn)"),
Applicability::MachineApplicable,
)
.emit();
}
}
Expand Down
22 changes: 12 additions & 10 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,18 @@ fn object_safety_violations_for_trait(
}),
);

violations.extend(
tcx.associated_items(trait_def_id)
.in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type)
.filter(|item| !tcx.generics_of(item.def_id).params.is_empty())
.map(|item| {
let ident = item.ident(tcx);
ObjectSafetyViolation::GAT(ident.name, ident.span)
}),
);
if !tcx.features().generic_associated_types_extended {
violations.extend(
tcx.associated_items(trait_def_id)
.in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type)
.filter(|item| !tcx.generics_of(item.def_id).params.is_empty())
.map(|item| {
let ident = item.ident(tcx);
ObjectSafetyViolation::GAT(ident.name, ident.span)
}),
);
}

debug!(
"object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
Expand Down
70 changes: 66 additions & 4 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use rustc_hir::lang_items::LangItem;
use rustc_index::bit_set::GrowableBitSet;
use rustc_infer::infer::InferOk;
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
use rustc_middle::ty::{self, GenericParamDefKind, Ty};
use rustc_middle::ty::{ToPolyTraitRef, ToPredicate};
use rustc_span::def_id::DefId;

Expand Down Expand Up @@ -487,18 +487,80 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.collect();

for assoc_type in assoc_types {
if !tcx.generics_of(assoc_type).params.is_empty() {
let defs: &ty::Generics = tcx.generics_of(assoc_type);

if !defs.params.is_empty() && !tcx.features().generic_associated_types_extended {
tcx.sess.delay_span_bug(
obligation.cause.span,
"GATs in trait object shouldn't have been considered",
);
return Err(SelectionError::Unimplemented);
}

// This maybe belongs in wf, but that can't (doesn't) handle
// higher-ranked things.
// Prevent, e.g., `dyn Iterator<Item = str>`.
for bound in self.tcx().item_bounds(assoc_type) {
let subst_bound = bound.subst(tcx, trait_predicate.trait_ref.substs);
let subst_bound =
if defs.count() == 0 {
bound.subst(tcx, trait_predicate.trait_ref.substs)
} else {
let mut substs = smallvec::SmallVec::with_capacity(defs.count());
substs.extend(trait_predicate.trait_ref.substs.iter());
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
smallvec::SmallVec::with_capacity(
bound.kind().bound_vars().len() + defs.count(),
);
bound_vars.extend(bound.kind().bound_vars().into_iter());
InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param
.kind
{
GenericParamDefKind::Type { .. } => {
let kind = ty::BoundTyKind::Param(param.name);
let bound_var = ty::BoundVariableKind::Ty(kind);
bound_vars.push(bound_var);
tcx.mk_ty(ty::Bound(
ty::INNERMOST,
ty::BoundTy {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind,
},
))
.into()
}
GenericParamDefKind::Lifetime => {
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Region(kind);
bound_vars.push(bound_var);
tcx.mk_region(ty::ReLateBound(
ty::INNERMOST,
ty::BoundRegion {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind,
},
))
.into()
}
GenericParamDefKind::Const { .. } => {
let bound_var = ty::BoundVariableKind::Const;
bound_vars.push(bound_var);
tcx.mk_const(ty::ConstS {
ty: tcx.type_of(param.def_id),
val: ty::ConstKind::Bound(
ty::INNERMOST,
ty::BoundVar::from_usize(bound_vars.len() - 1),
),
})
.into()
}
});
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
let assoc_ty_substs = tcx.intern_substs(&substs);

let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
let bound = bound.kind().skip_binder().subst(tcx, assoc_ty_substs);
tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
};
let normalized_bound = normalize_with_depth_to(
self,
obligation.param_env,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_typeck/src/check/inherited.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
}
}

/// Helper type of a temporary returned by `Inherited::build(...)`.
/// Necessary because we can't write the following bound:
/// `F: for<'b, 'tcx> where 'tcx FnOnce(Inherited<'b, 'tcx>)`.
/// A temporary returned by `Inherited::build(...)`. This is necessary
/// for multiple `InferCtxt` to share the same `in_progress_typeck_results`
/// without using `Rc` or something similar.
pub struct InheritedBuilder<'tcx> {
infcx: infer::InferCtxtBuilder<'tcx>,
def_id: LocalDefId,
Expand Down
Loading