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 8 pull requests #84375

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
30fc601
Tests for field is never read diagnostic
sunjay Mar 11, 2021
321aace
Added suggestion and note for when a field is never used
sunjay Mar 12, 2021
7faaf39
Updating test stderr files
sunjay Mar 12, 2021
789186d
Trying out a new message that works a little better for values *and* …
sunjay Mar 12, 2021
2acd8eb
New shorter diagnostic note that is different for items versus fields
sunjay Mar 13, 2021
3e34eb8
Putting help message only under the identifier that needs to be prefixed
sunjay Mar 25, 2021
539242a
Add a suggestion when using a type alias instead of trait alias
JohnTitor Mar 31, 2021
eea27b8
Mention trait alias on the E0404 note
JohnTitor Mar 31, 2021
9aa6c1e
fix 'const-stable since' for NonZeroU*::new_unchecked
RalfJung Apr 16, 2021
df01b3a
Document that `index` and `index_mut` can panic
wooster0 Apr 18, 2021
c86ffe9
Say that it "may panic"
wooster0 Apr 18, 2021
569096c
rustdoc: use details tag for trait implementors
jsha Apr 18, 2021
e85f19b
:arrow_up: rust-analyzer
lnicola Apr 20, 2021
8cc918a
Improve the docstrings of the `Lto` struct.
vext01 Apr 20, 2021
e9696c8
Implement a lint that highlights all moves larger than 1000 bytes
oli-obk Mar 26, 2021
a2f2179
Add an attribute to be able to configure the limit
oli-obk Mar 26, 2021
a46bc56
Tidy
oli-obk Mar 26, 2021
6e988c0
Typo
oli-obk Mar 26, 2021
85b1c67
Limit test to 64 bit systems to keep the sizes in the diagnostics stable
oli-obk Mar 29, 2021
b88fd86
Rollup merge of #83004 - sunjay:field-never-read-issue-81658, r=pnkfelix
GuillaumeGomez Apr 20, 2021
7468886
Rollup merge of #83519 - oli-obk:assign_shrink_your_normal_code, r=pn…
GuillaumeGomez Apr 20, 2021
ce47af0
Rollup merge of #83729 - JohnTitor:issue-43913, r=estebank
GuillaumeGomez Apr 20, 2021
4e18900
Rollup merge of #84251 - RalfJung:non-zero-const-since, r=kennytm
GuillaumeGomez Apr 20, 2021
619a00a
Rollup merge of #84301 - r00ster91:patch-1, r=kennytm
GuillaumeGomez Apr 20, 2021
166d1b7
Rollup merge of #84320 - jsha:details-implementors, r=Manishearth,Nem…
GuillaumeGomez Apr 20, 2021
12d0b25
Rollup merge of #84359 - lnicola:rust-analyzer-2021-04-20, r=jonas-sc…
GuillaumeGomez Apr 20, 2021
8864b91
Rollup merge of #84365 - vext01:improve-lto-docstrings, r=petrochenkov
GuillaumeGomez Apr 20, 2021
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
26 changes: 20 additions & 6 deletions compiler/rustc_error_codes/src/error_codes/E0404.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ struct Foo;
struct Bar;

impl Foo for Bar {} // error: `Foo` is not a trait
fn baz<T: Foo>(t: T) {} // error: `Foo` is not a trait
```

Another erroneous code example:

```compile_fail,E0404
struct Foo;
type Foo = Iterator<Item=String>;

fn bar<T: Foo>(t: T) {} // error: `Foo` is not a trait
fn bar<T: Foo>(t: T) {} // error: `Foo` is a type alias
```

Please verify that the trait's name was not misspelled or that the right
Expand All @@ -30,14 +31,27 @@ struct Bar;
impl Foo for Bar { // ok!
// functions implementation
}

fn baz<T: Foo>(t: T) {} // ok!
```

or:
Alternatively, you could introduce a new trait with your desired restrictions
as a super trait:

```
trait Foo {
// some functions
}
# trait Foo {}
# struct Bar;
# impl Foo for Bar {}
trait Qux: Foo {} // Anything that implements Qux also needs to implement Foo
fn baz<T: Qux>(t: T) {} // also ok!
```

Finally, if you are on nightly and want to use a trait alias
instead of a type alias, you should use `#![feature(trait_alias)]`:

```
#![feature(trait_alias)]
trait Foo = Iterator<Item=String>;

fn bar<T: Foo>(t: T) {} // ok!
```
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,9 @@ declare_features! (
/// Allows associated types in inherent impls.
(active, inherent_associated_types, "1.52.0", Some(8995), None),

// Allows setting the threshold for the `large_assignments` lint.
(active, large_assignments, "1.52.0", Some(83518), None),

/// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries.
(active, c_unwind, "1.52.0", Some(74990), None),

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
const_eval_limit, CrateLevel, template!(NameValueStr: "N"), const_eval_limit,
experimental!(const_eval_limit)
),
gated!(
move_size_limit, CrateLevel, template!(NameValueStr: "N"), large_assignments,
experimental!(move_size_limit)
),

// Entry point:
ungated!(main, Normal, template!(Word)),
Expand Down
34 changes: 34 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2877,6 +2877,39 @@ declare_lint! {
};
}

declare_lint! {
/// The `large_assignments` lint detects when objects of large
/// types are being moved around.
///
/// ### Example
///
/// ```rust,ignore (can crash on some platforms)
/// let x = [0; 50000];
/// let y = x;
/// ```
///
/// produces:
///
/// ```text
/// warning: moving a large value
/// --> $DIR/move-large.rs:1:3
/// let y = x;
/// - Copied large value here
/// ```
///
/// ### Explanation
///
/// When using a large type in a plain assignment or in a function
/// argument, idiomatic code can be inefficient.
/// Ideally appropriate optimizations would resolve this, but such
/// optimizations are only done in a best-effort manner.
/// This lint will trigger on all sites of large moves and thus allow the
/// user to resolve them in code.
pub LARGE_ASSIGNMENTS,
Warn,
"detects large moves or copies",
}

declare_lint_pass! {
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
Expand Down Expand Up @@ -2962,6 +2995,7 @@ declare_lint_pass! {
LEGACY_DERIVE_HELPERS,
PROC_MACRO_BACK_COMPAT,
OR_PATTERNS_BACK_COMPAT,
LARGE_ASSIGNMENTS,
]
}

Expand Down
15 changes: 10 additions & 5 deletions compiler/rustc_middle/src/middle/limits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
//! Registering limits, recursion_limit, type_length_limit and const_eval_limit
//! Registering limits:
//! * recursion_limit,
//! * move_size_limit,
//! * type_length_limit, and
//! * const_eval_limit
//!
//! There are various parts of the compiler that must impose arbitrary limits
//! on how deeply they recurse to prevent stack overflow. Users can override
Expand All @@ -8,21 +12,22 @@
use crate::bug;
use rustc_ast as ast;
use rustc_data_structures::sync::OnceCell;
use rustc_session::{Limit, Session};
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};

use std::num::IntErrorKind;

pub fn update_limits(sess: &Session, krate: &ast::Crate) {
update_limit(sess, krate, &sess.recursion_limit, sym::recursion_limit, 128);
update_limit(sess, krate, &sess.move_size_limit, sym::move_size_limit, 0);
update_limit(sess, krate, &sess.type_length_limit, sym::type_length_limit, 1048576);
update_limit(sess, krate, &sess.const_eval_limit, sym::const_eval_limit, 1_000_000);
}

fn update_limit(
sess: &Session,
krate: &ast::Crate,
limit: &OnceCell<Limit>,
limit: &OnceCell<impl From<usize> + std::fmt::Debug>,
name: Symbol,
default: usize,
) {
Expand All @@ -34,7 +39,7 @@ fn update_limit(
if let Some(s) = attr.value_str() {
match s.as_str().parse() {
Ok(n) => {
limit.set(Limit::new(n)).unwrap();
limit.set(From::from(n)).unwrap();
return;
}
Err(e) => {
Expand Down Expand Up @@ -63,5 +68,5 @@ fn update_limit(
}
}
}
limit.set(Limit::new(default)).unwrap();
limit.set(From::from(default)).unwrap();
}
25 changes: 24 additions & 1 deletion compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ use crate::ty::print::{FmtPrinter, Printer};
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::{self, List, Ty, TyCtxt};
use crate::ty::{AdtDef, InstanceDef, Region, ScalarInt, UserTypeAnnotationIndex};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
use rustc_hir::{self, GeneratorKind};
use rustc_hir::{self as hir, HirId};
use rustc_target::abi::{Size, VariantIdx};

use polonius_engine::Atom;
Expand Down Expand Up @@ -1948,6 +1948,29 @@ rustc_index::newtype_index! {
}
}

impl SourceScope {
/// Finds the original HirId this MIR item came from.
/// This is necessary after MIR optimizations, as otherwise we get a HirId
/// from the function that was inlined instead of the function call site.
pub fn lint_root(
self,
source_scopes: &IndexVec<SourceScope, SourceScopeData<'tcx>>,
) -> Option<HirId> {
let mut data = &source_scopes[self];
// FIXME(oli-obk): we should be able to just walk the `inlined_parent_scope`, but it
// does not work as I thought it would. Needs more investigation and documentation.
while data.inlined.is_some() {
trace!(?data);
data = &source_scopes[data.parent_scope.unwrap()];
}
trace!(?data);
match &data.local_data {
ClearCrossCrate::Set(data) => Some(data.lint_root),
ClearCrossCrate::Clear => None,
}
}
}

#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
pub struct SourceScopeData<'tcx> {
pub span: Span,
Expand Down
42 changes: 42 additions & 0 deletions compiler/rustc_mir/src/monomorphize/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,9 @@ use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable};
use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext};
use rustc_session::config::EntryFnType;
use rustc_session::lint::builtin::LARGE_ASSIGNMENTS;
use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP};
use rustc_target::abi::Size;
use smallvec::SmallVec;
use std::iter;
use std::ops::Range;
Expand Down Expand Up @@ -753,6 +755,46 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
self.super_terminator(terminator, location);
}

fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
self.super_operand(operand, location);
let limit = self.tcx.sess.move_size_limit();
if limit == 0 {
return;
}
let limit = Size::from_bytes(limit);
let ty = operand.ty(self.body, self.tcx);
let ty = self.monomorphize(ty);
let layout = self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty));
if let Ok(layout) = layout {
if layout.size > limit {
debug!(?layout);
let source_info = self.body.source_info(location);
debug!(?source_info);
let lint_root = source_info.scope.lint_root(&self.body.source_scopes);
debug!(?lint_root);
let lint_root = match lint_root {
Some(lint_root) => lint_root,
// This happens when the issue is in a function from a foreign crate that
// we monomorphized in the current crate. We can't get a `HirId` for things
// in other crates.
// FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
// but correct span? This would make the lint at least accept crate-level lint attributes.
None => return,
};
self.tcx.struct_span_lint_hir(
LARGE_ASSIGNMENTS,
lint_root,
source_info.span,
|lint| {
let mut err = lint.build(&format!("moving {} bytes", layout.size.bytes()));
err.span_label(source_info.span, "value moved from here");
err.emit()
},
);
}
}
}

fn visit_local(
&mut self,
_place_local: &Local,
Expand Down
19 changes: 4 additions & 15 deletions compiler/rustc_mir/src/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use rustc_middle::mir::visit::{
MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor,
};
use rustc_middle::mir::{
AssertKind, BasicBlock, BinOp, Body, ClearCrossCrate, Constant, ConstantKind, Local, LocalDecl,
LocalKind, Location, Operand, Place, Rvalue, SourceInfo, SourceScope, SourceScopeData,
Statement, StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE,
AssertKind, BasicBlock, BinOp, Body, Constant, ConstantKind, Local, LocalDecl, LocalKind,
Location, Operand, Place, Rvalue, SourceInfo, SourceScope, SourceScopeData, Statement,
StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE,
};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutError, TyAndLayout};
use rustc_middle::ty::subst::{InternalSubsts, Subst};
Expand Down Expand Up @@ -440,18 +440,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
}

fn lint_root(&self, source_info: SourceInfo) -> Option<HirId> {
let mut data = &self.source_scopes[source_info.scope];
// FIXME(oli-obk): we should be able to just walk the `inlined_parent_scope`, but it
// does not work as I thought it would. Needs more investigation and documentation.
while data.inlined.is_some() {
trace!(?data);
data = &self.source_scopes[data.parent_scope.unwrap()];
}
trace!(?data);
match &data.local_data {
ClearCrossCrate::Set(data) => Some(data.lint_root),
ClearCrossCrate::Clear => None,
}
source_info.scope.lint_root(&self.source_scopes)
}

fn use_ecx<F, T>(&mut self, f: F) -> Option<T>
Expand Down
Loading