diff --git a/Criterion/Internal.hs b/Criterion/Internal.hs
--- a/Criterion/Internal.hs
+++ b/Criterion/Internal.hs
@@ -36,6 +36,7 @@
 import Criterion.Monad (Criterion)
 import Criterion.Report (report)
 import Criterion.Types hiding (measure)
+import Criterion.Types.Internal (fakeEnvironment)
 import qualified Data.Map as Map
 import qualified Data.Vector as V
 import Statistics.Types (Estimate(..),ConfInt(..),confidenceInterval,cl95,confidenceLevel)
@@ -204,8 +205,7 @@
       foldM go idx [(addPrefix pfx desc, b) | b <- bs]
 
     shouldRun pfx mkbench =
-      any (select . addPrefix pfx) . benchNames . mkbench $
-      error "Criterion.env could not determine the list of your benchmarks since they force the environment (see the documentation for details)"
+      any (select . addPrefix pfx) . benchNames . mkbench $ fakeEnvironment
 
 -- | Write summary JSON file (if applicable)
 json :: [Report] -> Criterion ()
diff --git a/Criterion/Main.hs b/Criterion/Main.hs
--- a/Criterion/Main.hs
+++ b/Criterion/Main.hs
@@ -123,8 +123,8 @@
 -- > import Criterion.Main
 -- >
 -- > myConfig = defaultConfig {
--- >              -- Do not GC between runs.
--- >              forceGC = False
+-- >               -- Resample 10 times for bootstrapping
+-- >               resamples = 10
 -- >            }
 -- >
 -- > main = defaultMainWith myConfig [
diff --git a/Criterion/Main/Options.hs b/Criterion/Main/Options.hs
--- a/Criterion/Main/Options.hs
+++ b/Criterion/Main/Options.hs
@@ -1,5 +1,8 @@
 {-# LANGUAGE DeriveDataTypeable, DeriveGeneric, RecordWildCards #-}
 
+-- Disable deprecation warnings for now until we remove forceGC for good
+{-# OPTIONS_GHC -fno-warn-deprecations #-}
+
 -- |
 -- Module      : Criterion.Main.Options
 -- Copyright   : (c) 2014 Bryan O'Sullivan
@@ -50,7 +53,11 @@
                  -- ^ Match by prefix. For example, a prefix of
                  -- @\"foo\"@ will match @\"foobar\"@.
                | Glob
-                 -- ^ Match by Unix-style glob pattern.
+                 -- ^ Match by Unix-style glob pattern. When using this match
+                 -- type, benchmark names are treated as if they were
+                 -- file-paths. For example, the glob patterns @\"*/ba*\"@ and
+                 -- @\"*/*\"@ will match @\"foo/bar\"@, but @\"*\"@ or @\"*bar\"@
+                 -- __will not__.
                | Pattern
                  -- ^ Match by searching given substring in benchmark
                  -- paths.
diff --git a/Criterion/Types.hs b/Criterion/Types.hs
--- a/Criterion/Types.hs
+++ b/Criterion/Types.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE Trustworthy #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE DeriveDataTypeable, DeriveGeneric, GADTs, RecordWildCards #-}
@@ -74,9 +75,11 @@
 -- Temporary: to support pre-AMP GHC 7.8.4:
 import Control.Applicative
 import Data.Monoid
+import Data.Semigroup
 
 import Control.DeepSeq (NFData(rnf))
 import Control.Exception (evaluate)
+import Criterion.Types.Internal (fakeEnvironment)
 import Data.Aeson (FromJSON(..), ToJSON(..))
 import Data.Binary (Binary(..), putWord8, getWord8)
 import Data.Data (Data, Typeable)
@@ -130,7 +133,8 @@
     , template     :: FilePath
       -- ^ Template file to use if writing a report.
     } deriving (Eq, Read, Show, Typeable, Data, Generic)
-
+{-# DEPRECATED forceGC
+      ["forceGC will be removed in the next major criterion release."] #-}
 
 -- | A pure function or impure action that can be benchmarked. The
 -- 'Int64' parameter indicates the number of times to run the given
@@ -409,13 +413,15 @@
 --
 -- __Lazy pattern matching.__ In situations where a \"real\"
 -- environment is not needed, e.g. if a list of benchmark names is
--- being generated, @undefined@ will be passed to the function that
--- receives the environment.  This avoids the overhead of generating
--- an environment that will not actually be used.
+-- being generated, a value which throws an exception will be passed
+-- to the function that receives the environment.  This avoids the
+-- overhead of generating an environment that will not actually be
+-- used.
 --
 -- The function that receives the environment must use lazy pattern
--- matching to deconstruct the tuple, as use of strict pattern
--- matching will cause a crash if @undefined@ is passed in.
+-- matching to deconstruct the tuple (e.g., @~(x, y)@, not @(x, y)@),
+-- as use of strict pattern matching will cause a crash if an
+-- exception-throwing value is passed in.
 --
 -- __Example.__ This program runs benchmarks in an environment that
 -- contains two values.  The first value is the contents of a text
@@ -588,12 +594,12 @@
 -- | Retrieve the names of all benchmarks.  Grouped benchmarks are
 -- prefixed with the name of the group they're in.
 benchNames :: Benchmark -> [String]
-benchNames (Environment _ _ b) = benchNames (b undefined)
+benchNames (Environment _ _ b) = benchNames (b fakeEnvironment)
 benchNames (Benchmark d _)   = [d]
 benchNames (BenchGroup d bs) = map (addPrefix d) . concatMap benchNames $ bs
 
 instance Show Benchmark where
-    show (Environment _ _ b) = "Environment _ _" ++ show (b undefined)
+    show (Environment _ _ b) = "Environment _ _" ++ show (b fakeEnvironment)
     show (Benchmark d _)   = "Benchmark " ++ show d
     show (BenchGroup d _)  = "BenchGroup " ++ show d
 
@@ -650,9 +656,14 @@
             _ -> fail $ "get for OutlierEffect: unexpected " ++ show i
 instance NFData OutlierEffect
 
+instance Semigroup Outliers where
+    (<>) = addOutliers
+
 instance Monoid Outliers where
     mempty  = Outliers 0 0 0 0 0
+#if !(MIN_VERSION_base(4,11,0))
     mappend = addOutliers
+#endif
 
 addOutliers :: Outliers -> Outliers -> Outliers
 addOutliers (Outliers s a b c d) (Outliers t w x y z) =
diff --git a/Criterion/Types/Internal.hs b/Criterion/Types/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Criterion/Types/Internal.hs
@@ -0,0 +1,21 @@
+-- |
+-- Module      : Criterion.Types.Internal
+-- Copyright   : (c) 2017 Ryan Scott
+--
+-- License     : BSD-style
+-- Maintainer  : bos@serpentine.com
+-- Stability   : experimental
+-- Portability : GHC
+--
+-- Exports 'fakeEnvironment'.
+module Criterion.Types.Internal (fakeEnvironment) where
+
+-- | A dummy environment that is passed to functions that create benchmarks
+-- from environments when no concrete environment is available.
+fakeEnvironment :: env
+fakeEnvironment = error $ unlines
+  [ "Criterion atttempted to retrieve a non-existent environment!"
+  , "\tPerhaps you forgot to use lazy pattern matching in a function which"
+  , "\tconstructs benchmarks from an environment?"
+  , "\t(see the documentation for `env` for details)"
+  ]
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,14 @@
+1.2.3.0
+
+* Add a `Semigroup` instance for `Outliers`
+
+* Improve the error messages that are thrown when forcing nonexistent
+  benchmark environments.
+
+* Explicitly mark `forceGC` as deprecated. `forceGC` has not had any effect
+  for several releases, and it will be removed in the next major `criterion`
+  release.
+
 1.2.2.0
 
 * Important bugfix: versions 1.2.0.0 and 1.2.1.0 were incorrectly displaying
diff --git a/criterion.cabal b/criterion.cabal
--- a/criterion.cabal
+++ b/criterion.cabal
@@ -1,5 +1,5 @@
 name:           criterion
-version:        1.2.2.0
+version:        1.2.3.0
 synopsis:       Robust, reliable performance measurement and analysis
 license:        BSD3
 license-file:   LICENSE
@@ -65,6 +65,7 @@
 
   other-modules:
     Criterion.Monad.Internal
+    Criterion.Types.Internal
 
   c-sources: cbits/cycles.c
   if os(darwin)
@@ -101,6 +102,7 @@
     mwc-random >= 0.8.0.3,
     optparse-applicative >= 0.13,
     parsec >= 3.1.0,
+    semigroups,
     statistics >= 0.14 && < 0.15,
     text >= 0.11,
     time,
@@ -126,6 +128,7 @@
   GHC-Options:          -Wall -rtsopts
   Main-Is:              Report.hs
   Other-Modules:        Options
+                        Paths_criterion
   Hs-Source-Dirs:       app
 
   Build-Depends:
