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 10 pull requests #93173

Merged
merged 31 commits into from
Jan 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e3a048c
Ensure that early-bound function lifetimes are always 'local'
Aaron1011 Dec 31, 2021
90330b5
Improve error message for cfg arguments.
iwanders Jan 13, 2022
db56c6d
Update unit tests to accomodate for improved error.
iwanders Jan 13, 2022
2835ace
Improve suggestions for type errors with string concatenation
camelid Jan 13, 2022
69db5e2
Split up very long message
camelid Jan 13, 2022
935a99a
Add line breaks to make message easier to read
camelid Jan 13, 2022
6e42bc3
Fix formatting
camelid Jan 13, 2022
5296bae
Set the allocation MIN_ALIGN for espidf to 4.
MabezDev Jan 5, 2022
32be348
Add unit test for cfg-arg without quotes.
iwanders Jan 16, 2022
1531d26
Limit scope of the hint about escaping.
iwanders Jan 16, 2022
af87248
Update unit tests to match more limited hint about escaping.
iwanders Jan 16, 2022
ef46e38
Implement tuple array diagnostic
terrarier2111 Jan 14, 2022
b2dd137
Use let_else in even more places
est31 Jan 18, 2022
7507fb6
Shorten and improve messages
camelid Jan 19, 2022
7c4eca0
Make suggestions verbose
camelid Jan 19, 2022
7bc47cf
Correct docs in `Arc` and `Rc`.
JakobDegen Jan 20, 2022
4de7618
Remove unnecessary unsafe code in `Arc` deferred initialization examp…
JakobDegen Jan 20, 2022
fdf930c
delete `Stdin::split` forwarder
tlyu Jan 20, 2022
9d178e5
rustdoc: fix overflow-wrap for table layouts
jsha Jan 20, 2022
b27d59d
replace paths in PathSet with a dedicated TaskPath struct
pietroalbini Dec 15, 2021
b3ad405
allow excluding paths only from a single module
pietroalbini Dec 15, 2021
fc69406
Rollup merge of #91965 - ferrocene:pa-more-granular-exclude, r=Mark-S…
matthiaskrgr Jan 21, 2022
10c9ec3
Rollup merge of #92467 - Aaron1011:extern-local-region, r=oli-obk
matthiaskrgr Jan 21, 2022
701a833
Rollup merge of #92586 - esp-rs:bugfix/allocation-alignment-espidf, r…
matthiaskrgr Jan 21, 2022
e38cbc7
Rollup merge of #92835 - iwanders:issue-66450-improve-cfg-error-messa…
matthiaskrgr Jan 21, 2022
430673f
Rollup merge of #92843 - camelid:str-concat-sugg, r=davidtwco
matthiaskrgr Jan 21, 2022
1f3a2dd
Rollup merge of #92963 - terrarier2111:tuple-diagnostic, r=davidtwco
matthiaskrgr Jan 21, 2022
ab19d4a
Rollup merge of #93046 - est31:let_else, r=davidtwco
matthiaskrgr Jan 21, 2022
9474c74
Rollup merge of #93109 - JakobDegen:arc-docs, r=m-ou-se
matthiaskrgr Jan 21, 2022
081d65f
Rollup merge of #93134 - tlyu:delete-stdin-split, r=Amanieu
matthiaskrgr Jan 21, 2022
26e9357
Rollup merge of #93139 - jsha:fix-wrapped-names, r=Nemo157
matthiaskrgr Jan 21, 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
41 changes: 25 additions & 16 deletions compiler/rustc_borrowck/src/universal_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,9 @@ pub enum RegionClassification {
/// anywhere. There is only one, `'static`.
Global,

/// An **external** region is only relevant for closures. In that
/// case, it refers to regions that are free in the closure type
/// An **external** region is only relevant for
/// closures, generators, and inline consts. In that
/// case, it refers to regions that are free in the type
/// -- basically, something bound in the surrounding context.
///
/// Consider this example:
Expand All @@ -198,8 +199,8 @@ pub enum RegionClassification {
/// Here, the lifetimes `'a` and `'b` would be **external** to the
/// closure.
///
/// If we are not analyzing a closure, there are no external
/// lifetimes.
/// If we are not analyzing a closure/generator/inline-const,
/// there are no external lifetimes.
External,

/// A **local** lifetime is one about which we know the full set
Expand Down Expand Up @@ -424,22 +425,30 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {

let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.did.to_def_id());

// If this is a closure or generator, then the late-bound regions from the enclosing
// function are actually external regions to us. For example, here, 'a is not local
// to the closure c (although it is local to the fn foo):
// fn foo<'a>() {
// let c = || { let x: &'a u32 = ...; }
// }
if self.mir_def.did.to_def_id() != typeck_root_def_id {
// If this is is a 'root' body (not a closure/generator/inline const), then
// there are no extern regions, so the local regions start at the same
// position as the (empty) sub-list of extern regions
let first_local_index = if self.mir_def.did.to_def_id() == typeck_root_def_id {
first_extern_index
} else {
// If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing
// function are actually external regions to us. For example, here, 'a is not local
// to the closure c (although it is local to the fn foo):
// fn foo<'a>() {
// let c = || { let x: &'a u32 = ...; }
// }
self.infcx
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices)
}

let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
.replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices);
// Any regions created during the execution of `defining_ty` or during the above
// late-bound region replacement are all considered 'extern' regions
self.infcx.num_region_vars()
};

// "Liberate" the late-bound regions. These correspond to
// "local" free regions.
let first_local_index = self.infcx.num_region_vars();

let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);

let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
FR,
self.mir_def.did,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1493,7 +1493,7 @@ fn generator_layout_and_saved_local_names<'tcx>(

let state_arg = mir::Local::new(1);
for var in &body.var_debug_info {
let place = if let mir::VarDebugInfoContents::Place(p) = var.value { p } else { continue };
let mir::VarDebugInfoContents::Place(place) = &var.value else { continue };
if place.local != state_arg {
continue;
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/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/nightly-rustc/")]
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(let_else)]
#![feature(extern_types)]
#![feature(nll)]
#![recursion_limit = "256"]
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,16 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
Err(errs) => errs.into_iter().for_each(|mut err| err.cancel()),
}

error!(r#"expected `key` or `key="value"`"#);
// If the user tried to use a key="value" flag, but is missing the quotes, provide
// a hint about how to resolve this.
if s.contains("=") && !s.contains("=\"") && !s.ends_with("\"") {
error!(concat!(
r#"expected `key` or `key="value"`, ensure escaping is appropriate"#,
r#" for your shell, try 'key="value"' or key=\"value\""#
));
} else {
error!(r#"expected `key` or `key="value"`"#);
}
})
.collect::<CrateConfig>();
cfg.into_iter().map(|(a, b)| (a.to_string(), b.map(|b| b.to_string()))).collect()
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(let_else)]
#![feature(internal_output_capture)]
#![feature(thread_spawn_unchecked)]
#![feature(nll)]
Expand Down
92 changes: 46 additions & 46 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,57 +717,57 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
}

fn should_ignore_fn(ret_ty: &ast::FnRetTy) -> bool {
if let ast::FnRetTy::Ty(ref ty) = ret_ty {
fn involves_impl_trait(ty: &ast::Ty) -> bool {
match ty.kind {
ast::TyKind::ImplTrait(..) => true,
ast::TyKind::Slice(ref subty)
| ast::TyKind::Array(ref subty, _)
| ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. })
| ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. })
| ast::TyKind::Paren(ref subty) => involves_impl_trait(subty),
ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()),
ast::TyKind::Path(_, ref path) => {
path.segments.iter().any(|seg| match seg.args.as_deref() {
None => false,
Some(&ast::GenericArgs::AngleBracketed(ref data)) => {
data.args.iter().any(|arg| match arg {
ast::AngleBracketedArg::Arg(arg) => match arg {
ast::GenericArg::Type(ty) => involves_impl_trait(ty),
ast::GenericArg::Lifetime(_)
| ast::GenericArg::Const(_) => false,
},
ast::AngleBracketedArg::Constraint(c) => match c.kind {
ast::AssocConstraintKind::Bound { .. } => true,
ast::AssocConstraintKind::Equality { ref term } => {
match term {
Term::Ty(ty) => involves_impl_trait(ty),
// FIXME(...): This should check if the constant
// involves a trait impl, but for now ignore.
Term::Const(_) => false,
}
let ast::FnRetTy::Ty(ref ty) = ret_ty else {
return false;
};
fn involves_impl_trait(ty: &ast::Ty) -> bool {
match ty.kind {
ast::TyKind::ImplTrait(..) => true,
ast::TyKind::Slice(ref subty)
| ast::TyKind::Array(ref subty, _)
| ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. })
| ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. })
| ast::TyKind::Paren(ref subty) => involves_impl_trait(subty),
ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()),
ast::TyKind::Path(_, ref path) => {
path.segments.iter().any(|seg| match seg.args.as_deref() {
None => false,
Some(&ast::GenericArgs::AngleBracketed(ref data)) => {
data.args.iter().any(|arg| match arg {
ast::AngleBracketedArg::Arg(arg) => match arg {
ast::GenericArg::Type(ty) => involves_impl_trait(ty),
ast::GenericArg::Lifetime(_) | ast::GenericArg::Const(_) => {
false
}
},
ast::AngleBracketedArg::Constraint(c) => match c.kind {
ast::AssocConstraintKind::Bound { .. } => true,
ast::AssocConstraintKind::Equality { ref term } => {
match term {
Term::Ty(ty) => involves_impl_trait(ty),
// FIXME(...): This should check if the constant
// involves a trait impl, but for now ignore.
Term::Const(_) => false,
}
},
})
}
Some(&ast::GenericArgs::Parenthesized(ref data)) => {
any_involves_impl_trait(data.inputs.iter())
|| ReplaceBodyWithLoop::should_ignore_fn(&data.output)
}
})
}
_ => false,
}
},
})
}
Some(&ast::GenericArgs::Parenthesized(ref data)) => {
any_involves_impl_trait(data.inputs.iter())
|| ReplaceBodyWithLoop::should_ignore_fn(&data.output)
}
})
}
_ => false,
}
}

fn any_involves_impl_trait<'a, I: Iterator<Item = &'a P<ast::Ty>>>(mut it: I) -> bool {
it.any(|subty| involves_impl_trait(subty))
}

involves_impl_trait(ty)
} else {
false
fn any_involves_impl_trait<'a, I: Iterator<Item = &'a P<ast::Ty>>>(mut it: I) -> bool {
it.any(|subty| involves_impl_trait(subty))
}

involves_impl_trait(ty)
}

fn is_sig_const(sig: &ast::FnSig) -> bool {
Expand Down
31 changes: 15 additions & 16 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1347,23 +1347,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

let mut otherwise = None;
for match_pair in match_pairs {
if let PatKind::Or { ref pats } = *match_pair.pattern.kind {
let or_span = match_pair.pattern.span;
let place = match_pair.place;

first_candidate.visit_leaves(|leaf_candidate| {
self.test_or_pattern(
leaf_candidate,
&mut otherwise,
pats,
or_span,
place.clone(),
fake_borrows,
);
});
} else {
let PatKind::Or { ref pats } = &*match_pair.pattern.kind else {
bug!("Or-patterns should have been sorted to the end");
}
};
let or_span = match_pair.pattern.span;
let place = match_pair.place;

first_candidate.visit_leaves(|leaf_candidate| {
self.test_or_pattern(
leaf_candidate,
&mut otherwise,
pats,
or_span,
place.clone(),
fake_borrows,
);
});
}

let remainder_start = otherwise.unwrap_or_else(|| self.cfg.start_new_block());
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_mir_build/src/build/matches/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
switch_ty: Ty<'tcx>,
options: &mut FxIndexMap<&'tcx ty::Const<'tcx>, u128>,
) -> bool {
let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) {
Some(match_pair) => match_pair,
_ => {
return false;
}
let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else {
return false;
};

match *match_pair.pattern.kind {
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1171,9 +1171,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
ident: Symbol,
kind: &AssocItemKind,
) -> Option<Symbol> {
let module = if let Some((module, _)) = self.current_trait_ref {
module
} else {
let Some((module, _)) = &self.current_trait_ref else {
return None;
};
if ident == kw::Underscore {
Expand Down
75 changes: 37 additions & 38 deletions compiler/rustc_resolve/src/late/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1000,46 +1000,45 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// `fn foo<'a>() -> MyAnonTy<'a> { ... }`
// ^ ^this gets resolved in the current scope
for lifetime in lifetimes {
if let hir::GenericArg::Lifetime(lifetime) = lifetime {
self.visit_lifetime(lifetime);
let hir::GenericArg::Lifetime(lifetime) = lifetime else {
continue
};
self.visit_lifetime(lifetime);

// Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
// and ban them. Type variables instantiated inside binders aren't
// well-supported at the moment, so this doesn't work.
// In the future, this should be fixed and this error should be removed.
let def = self.map.defs.get(&lifetime.hir_id).cloned();
let Some(Region::LateBound(_, _, def_id, _)) = def else {
continue
};
let Some(def_id) = def_id.as_local() else {
continue
};
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
// Ensure that the parent of the def is an item, not HRTB
let parent_id = self.tcx.hir().get_parent_node(hir_id);
// FIXME(cjgillot) Can this check be replaced by
// `let parent_is_item = parent_id.is_owner();`?
let parent_is_item = if let Some(parent_def_id) = parent_id.as_owner() {
matches!(self.tcx.hir().krate().owners.get(parent_def_id), Some(Some(_)),)
} else {
false
};

// Check for predicates like `impl for<'a> Trait<impl OtherTrait<'a>>`
// and ban them. Type variables instantiated inside binders aren't
// well-supported at the moment, so this doesn't work.
// In the future, this should be fixed and this error should be removed.
let def = self.map.defs.get(&lifetime.hir_id).cloned();
if let Some(Region::LateBound(_, _, def_id, _)) = def {
if let Some(def_id) = def_id.as_local() {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
// Ensure that the parent of the def is an item, not HRTB
let parent_id = self.tcx.hir().get_parent_node(hir_id);
// FIXME(cjgillot) Can this check be replaced by
// `let parent_is_item = parent_id.is_owner();`?
let parent_is_item =
if let Some(parent_def_id) = parent_id.as_owner() {
matches!(
self.tcx.hir().krate().owners.get(parent_def_id),
Some(Some(_)),
)
} else {
false
};

if !parent_is_item {
if !self.trait_definition_only {
struct_span_err!(
self.tcx.sess,
lifetime.span,
E0657,
"`impl Trait` can only capture lifetimes \
bound at the fn or impl level"
)
.emit();
}
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
}
}
if !parent_is_item {
if !self.trait_definition_only {
struct_span_err!(
self.tcx.sess,
lifetime.span,
E0657,
"`impl Trait` can only capture lifetimes \
bound at the fn or impl level"
)
.emit();
}
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
}
}

Expand Down
Loading