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 13 pull requests #77082

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
d4039c5
wip emit errors during AbstractConst building
lcnr Sep 19, 2020
30cbc97
words
lcnr Sep 19, 2020
16047d4
fix typo in docs and comments
yuk1ty Sep 21, 2020
e734733
Record `tcx.def_span` instead of `item.span` in crate metadata
Aaron1011 Sep 19, 2020
7a02ebd
bless tests
lcnr Sep 21, 2020
9a493ce
add test for closures in abstract consts
lcnr Sep 21, 2020
37463d4
Uplift temporary-cstring-as-ptr into rustc
nathanwhit Aug 18, 2020
4d8a9f1
Add basic test
nathanwhit Aug 18, 2020
1e1c9c5
Address review comments
nathanwhit Aug 18, 2020
80d41c9
Update doctest
nathanwhit Aug 18, 2020
d2a2429
Tweak diagnostic
nathanwhit Aug 18, 2020
dc2cbb3
Change to warn by default / fix typo
nathanwhit Aug 23, 2020
79e61a0
Address review comments
nathanwhit Sep 21, 2020
2f893e4
review
lcnr Sep 21, 2020
2a40b63
Update addr.rs
imbolc Sep 22, 2020
4a6bc77
Liballoc bench vec use mem take not replace
pickfire Sep 22, 2020
731113b
Miri: more informative deallocation error messages
RalfJung Sep 22, 2020
0082d20
Typo fix: "satsify" -> "satisfy"
follower Sep 22, 2020
05c3a2b
Add #[track_caller] to more panicking Cell functions
est31 Sep 22, 2020
5ab714f
Update library/std/src/net/addr.rs
imbolc Sep 22, 2020
4622ceb
Update library/std/src/net/addr.rs
imbolc Sep 22, 2020
37b72bc
Write docs for lint / fix review nit
nathanwhit Sep 22, 2020
9f5c3e9
Remove lint from clippy
nathanwhit Sep 22, 2020
4cc16db
Fix doctest
nathanwhit Sep 22, 2020
3dd28c7
Useful derives on `ops::Status`
ecstatic-morse Sep 17, 2020
110e59e
Update library functions with stability attributes
ecstatic-morse Sep 17, 2020
a173c5c
Add const-stability helpers
ecstatic-morse Sep 17, 2020
7fb9587
Return `true` if `check_const` emits an error
ecstatic-morse Sep 17, 2020
bfc10a8
Allow errors to abort const checking when emitted
ecstatic-morse Sep 17, 2020
5ee5429
Add structured errors for `qualify_min_const_fn` checks
ecstatic-morse Sep 17, 2020
3569bb6
Update const-checker to replicate `qualify_min_const_fn`
ecstatic-morse Sep 17, 2020
ef6d427
Bless tests
ecstatic-morse Sep 17, 2020
9be3d10
Bless compile-fail
ecstatic-morse Sep 17, 2020
d60e204
Use the same name everywhere for `is_const_stable_const_fn`
ecstatic-morse Sep 18, 2020
08e3822
Replace missing comment
ecstatic-morse Sep 18, 2020
6044836
Add `#![feature(const_fn_transmute)]` to `rustc_ast`
ecstatic-morse Sep 22, 2020
186d148
Use correct feature gate for unsizing casts
ecstatic-morse Sep 22, 2020
4b6a482
Fix dest prop miscompilation around references
jonas-schievink Sep 22, 2020
928a29f
Bless mir-opt tests
jonas-schievink Sep 22, 2020
c078905
Don't use an if guard to check equality with a constant
LingMan Sep 22, 2020
d76b807
Merge two almost identical match arms
LingMan Sep 22, 2020
1871d90
Rollup merge of #75671 - nathanwhit:cstring-temp-lint, r=oli-obk
ecstatic-morse Sep 22, 2020
00569c3
Rollup merge of #76850 - ecstatic-morse:const-checking-refactor, r=ol…
ecstatic-morse Sep 22, 2020
176af83
Rollup merge of #76898 - Aaron1011:fix/item-def-span, r=oli-obk
ecstatic-morse Sep 22, 2020
dc47b2c
Rollup merge of #76939 - lcnr:const-evaluatable-cont, r=oli-obk
ecstatic-morse Sep 22, 2020
f951295
Rollup merge of #76994 - yuk1ty:fix-small-typo, r=estebank
ecstatic-morse Sep 22, 2020
cff8489
Rollup merge of #77042 - imbolc:patch-2, r=kennytm
ecstatic-morse Sep 22, 2020
a41b5cc
Rollup merge of #77044 - pickfire:patch-4, r=jyn514
ecstatic-morse Sep 22, 2020
89e73d5
Rollup merge of #77047 - RalfJung:miri-dealloc, r=oli-obk
ecstatic-morse Sep 22, 2020
51ba922
Rollup merge of #77050 - follower:patch-1, r=oli-obk
ecstatic-morse Sep 22, 2020
1d603db
Rollup merge of #77055 - est31:more_track_caller, r=Mark-Simulacrum
ecstatic-morse Sep 22, 2020
0b141e5
Rollup merge of #77066 - jonas-schievink:dest-prop-borrow, r=oli-obk
ecstatic-morse Sep 22, 2020
3748c26
Rollup merge of #77078 - LingMan:patch-2, r=jonas-schievink
ecstatic-morse Sep 22, 2020
f7c06ea
Rollup merge of #77081 - LingMan:patch-1, r=jonas-schievink
ecstatic-morse Sep 22, 2020
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: 1 addition & 0 deletions compiler/rustc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
#![feature(box_syntax)]
#![feature(const_fn)] // For the `transmute` in `P::new`
#![feature(const_fn_transmute)]
#![feature(const_panic)]
#![feature(crate_visibility_modifier)]
#![feature(label_break_value)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ where
.emit();
};
match issue.parse() {
Ok(num) if num == 0 => {
Ok(0) => {
emit_diag(
"`issue` must not be \"0\", \
use \"none\" instead",
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_builtin_macros/src/format_foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,7 @@ pub mod printf {
.and_then(|end| end.at_next_cp())
.map(|end| (next.slice_between(end).unwrap(), end));
let end = match end {
Some(("32", end)) => end,
Some(("64", end)) => end,
Some(("32" | "64", end)) => end,
_ => next,
};
state = Type;
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ mod early;
mod internal;
mod late;
mod levels;
mod methods;
mod non_ascii_idents;
mod nonstandard_style;
mod passes;
Expand All @@ -72,6 +73,7 @@ use rustc_span::Span;
use array_into_iter::ArrayIntoIter;
use builtin::*;
use internal::*;
use methods::*;
use non_ascii_idents::*;
use nonstandard_style::*;
use redundant_semicolon::*;
Expand Down Expand Up @@ -157,6 +159,7 @@ macro_rules! late_lint_passes {
MissingDebugImplementations: MissingDebugImplementations::default(),
ArrayIntoIter: ArrayIntoIter,
ClashingExternDeclarations: ClashingExternDeclarations::new(),
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
]
);
};
Expand Down
106 changes: 106 additions & 0 deletions compiler/rustc_lint/src/methods.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use crate::LateContext;
use crate::LateLintPass;
use crate::LintContext;
use rustc_hir::{Expr, ExprKind, PathSegment};
use rustc_middle::ty;
use rustc_span::{symbol::sym, ExpnKind, Span};

declare_lint! {
/// The `temporary_cstring_as_ptr` lint detects getting the inner pointer of
/// a temporary `CString`.
///
/// ### Example
///
/// ```rust
/// # #![allow(unused)]
/// # use std::ffi::CString;
/// let c_str = CString::new("foo").unwrap().as_ptr();
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The inner pointer of a `CString` lives only as long as the `CString` it
/// points to. Getting the inner pointer of a *temporary* `CString` allows the `CString`
/// to be dropped at the end of the statement, as it is not being referenced as far as the typesystem
/// is concerned. This means outside of the statement the pointer will point to freed memory, which
/// causes undefined behavior if the pointer is later dereferenced.
pub TEMPORARY_CSTRING_AS_PTR,
Warn,
"detects getting the inner pointer of a temporary `CString`"
}

declare_lint_pass!(TemporaryCStringAsPtr => [TEMPORARY_CSTRING_AS_PTR]);

fn in_macro(span: Span) -> bool {
if span.from_expansion() {
!matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(..))
} else {
false
}
}

fn first_method_call<'tcx>(
expr: &'tcx Expr<'tcx>,
) -> Option<(&'tcx PathSegment<'tcx>, &'tcx [Expr<'tcx>])> {
if let ExprKind::MethodCall(path, _, args, _) = &expr.kind {
if args.iter().any(|e| e.span.from_expansion()) { None } else { Some((path, *args)) }
} else {
None
}
}

impl<'tcx> LateLintPass<'tcx> for TemporaryCStringAsPtr {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if in_macro(expr.span) {
return;
}

match first_method_call(expr) {
Some((path, args)) if path.ident.name == sym::as_ptr => {
let unwrap_arg = &args[0];
let as_ptr_span = path.ident.span;
match first_method_call(unwrap_arg) {
Some((path, args))
if path.ident.name == sym::unwrap || path.ident.name == sym::expect =>
{
let source_arg = &args[0];
lint_cstring_as_ptr(cx, as_ptr_span, source_arg, unwrap_arg);
}
_ => return,
}
}
_ => return,
}
}
}

fn lint_cstring_as_ptr(
cx: &LateContext<'_>,
as_ptr_span: Span,
source: &rustc_hir::Expr<'_>,
unwrap: &rustc_hir::Expr<'_>,
) {
let source_type = cx.typeck_results().expr_ty(source);
if let ty::Adt(def, substs) = source_type.kind() {
if cx.tcx.is_diagnostic_item(sym::result_type, def.did) {
if let ty::Adt(adt, _) = substs.type_at(0).kind() {
if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did) {
cx.struct_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, |diag| {
let mut diag = diag
.build("getting the inner pointer of a temporary `CString`");
diag.span_label(as_ptr_span, "this pointer will be invalid");
diag.span_label(
unwrap.span,
"this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime",
);
diag.note("pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned");
diag.help("for more information, see https://doc.rust-lang.org/reference/destructors.html");
diag.emit();
});
}
}
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ fn get_nullable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
}

/// Check if this enum can be safely exported based on the "nullable pointer optimization". If it
/// can, return the the type that `ty` can be safely converted to, otherwise return `None`.
/// can, return the type that `ty` can be safely converted to, otherwise return `None`.
/// Currently restricted to function pointers, boxes, references, `core::num::NonZero*`,
/// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes.
/// FIXME: This duplicates code in codegen.
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{AtomicCell, Lock, LockGuard, Lrc, OnceCell};
use rustc_errors::ErrorReported;
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive};
use rustc_hir as hir;
Expand Down Expand Up @@ -1201,13 +1202,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
&self,
tcx: TyCtxt<'tcx>,
id: DefIndex,
) -> Option<&'tcx [mir::abstract_const::Node<'tcx>]> {
) -> Result<Option<&'tcx [mir::abstract_const::Node<'tcx>]>, ErrorReported> {
self.root
.tables
.mir_abstract_consts
.get(self, id)
.filter(|_| !self.is_proc_macro(id))
.map_or(None, |v| Some(v.decode((self, tcx))))
.map_or(Ok(None), |v| Ok(Some(v.decode((self, tcx)))))
}

fn get_unused_generic_params(&self, id: DefIndex) -> FiniteBitSet<u32> {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ impl EncodeContext<'a, 'tcx> {
}

let abstract_const = self.tcx.mir_abstract_const(def_id);
if let Some(abstract_const) = abstract_const {
if let Ok(Some(abstract_const)) = abstract_const {
record!(self.tables.mir_abstract_consts[def_id.to_def_id()] <- abstract_const);
}
}
Expand Down Expand Up @@ -1300,7 +1300,7 @@ impl EncodeContext<'a, 'tcx> {
});
record!(self.tables.visibility[def_id] <-
ty::Visibility::from_hir(&item.vis, item.hir_id, tcx));
record!(self.tables.span[def_id] <- item.span);
record!(self.tables.span[def_id] <- self.tcx.def_span(def_id));
record!(self.tables.attributes[def_id] <- item.attrs);
// FIXME(eddyb) there should be a nicer way to do this.
match item.kind {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ pub enum ErrorHandled {
TooGeneric,
}

impl From<ErrorReported> for ErrorHandled {
fn from(err: ErrorReported) -> ErrorHandled {
ErrorHandled::Reported(err)
}
}

CloneTypeFoldableAndLiftImpls! {
ErrorHandled,
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/predecessors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl PredecessorCache {
self.cache = OnceCell::new();
}

/// Returns the the predecessor graph for this MIR.
/// Returns the predecessor graph for this MIR.
#[inline]
pub(super) fn compute(
&self,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,15 +247,15 @@ rustc_queries! {
/// Try to build an abstract representation of the given constant.
query mir_abstract_const(
key: DefId
) -> Option<&'tcx [mir::abstract_const::Node<'tcx>]> {
) -> Result<Option<&'tcx [mir::abstract_const::Node<'tcx>]>, ErrorReported> {
desc {
|tcx| "building an abstract representation for {}", tcx.def_path_str(key),
}
}
/// Try to build an abstract representation of the given constant.
query mir_abstract_const_of_const_arg(
key: (LocalDefId, DefId)
) -> Option<&'tcx [mir::abstract_const::Node<'tcx>]> {
) -> Result<Option<&'tcx [mir::abstract_const::Node<'tcx>]>, ErrorReported> {
desc {
|tcx|
"building an abstract representation for the const argument {}",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/borrow_check/member_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
/// Pushes a member constraint into the set.
///
/// The input member constraint `m_c` is in the form produced by
/// the the `rustc_middle::infer` code.
/// the `rustc_middle::infer` code.
///
/// The `to_region_vid` callback fn is used to convert the regions
/// within into `RegionVid` format -- it typically consults the
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_mir/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
None => {
// Deallocating global memory -- always an error
return Err(match self.tcx.get_global_alloc(ptr.alloc_id) {
Some(GlobalAlloc::Function(..)) => err_ub_format!("deallocating a function"),
Some(GlobalAlloc::Function(..)) => {
err_ub_format!("deallocating {}, which is a function", ptr.alloc_id)
}
Some(GlobalAlloc::Static(..) | GlobalAlloc::Memory(..)) => {
err_ub_format!("deallocating static memory")
err_ub_format!("deallocating {}, which is static memory", ptr.alloc_id)
}
None => err_ub!(PointerUseAfterFree(ptr.alloc_id)),
}
Expand All @@ -297,15 +299,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {

if alloc_kind != kind {
throw_ub_format!(
"deallocating {} memory using {} deallocation operation",
"deallocating {}, which is {} memory, using {} deallocation operation",
ptr.alloc_id,
alloc_kind,
kind
);
}
if let Some((size, align)) = old_size_and_align {
if size != alloc.size || align != alloc.align {
throw_ub_format!(
"incorrect layout on deallocation: allocation has size {} and alignment {}, but gave size {} and alignment {}",
"incorrect layout on deallocation: {} has size {} and alignment {}, but gave size {} and alignment {}",
ptr.alloc_id,
alloc.size.bytes(),
alloc.align.bytes(),
size.bytes(),
Expand Down
40 changes: 40 additions & 0 deletions compiler/rustc_mir/src/transform/check_consts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ impl ConstCx<'mir, 'tcx> {
pub fn const_kind(&self) -> hir::ConstContext {
self.const_kind.expect("`const_kind` must not be called on a non-const fn")
}

pub fn is_const_stable_const_fn(&self) -> bool {
self.const_kind == Some(hir::ConstContext::ConstFn)
&& self.tcx.features().staged_api
&& is_const_stable_const_fn(self.tcx, self.def_id.to_def_id())
}
}

/// Returns `true` if this `DefId` points to one of the official `panic` lang items.
Expand All @@ -63,3 +69,37 @@ pub fn allow_internal_unstable(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: S
attr::allow_internal_unstable(&tcx.sess, attrs)
.map_or(false, |mut features| features.any(|name| name == feature_gate))
}

// Returns `true` if the given `const fn` is "const-stable".
//
// Panics if the given `DefId` does not refer to a `const fn`.
//
// Const-stability is only relevant for `const fn` within a `staged_api` crate. Only "const-stable"
// functions can be called in a const-context by users of the stable compiler. "const-stable"
// functions are subject to more stringent restrictions than "const-unstable" functions: They
// cannot use unstable features and can only call other "const-stable" functions.
pub fn is_const_stable_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
use attr::{ConstStability, Stability, StabilityLevel};

// Const-stability is only relevant for `const fn`.
assert!(tcx.is_const_fn_raw(def_id));

// Functions with `#[rustc_const_unstable]` are const-unstable.
match tcx.lookup_const_stability(def_id) {
Some(ConstStability { level: StabilityLevel::Unstable { .. }, .. }) => return false,
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => return true,
None => {}
}

// Functions with `#[unstable]` are const-unstable.
//
// FIXME(ecstaticmorse): We should keep const-stability attributes wholly separate from normal stability
// attributes. `#[unstable]` should be irrelevant.
if let Some(Stability { level: StabilityLevel::Unstable { .. }, .. }) =
tcx.lookup_stability(def_id)
{
return false;
}

true
}
Loading